单链表常见面试题(二)

来源:互联网 发布:视频播放器编程 编辑:程序博客网 时间:2024/06/05 05:03

1.判断单链表是否带环?若带环,求环的长度?求环的入口点?


(1)判断是否带环

Node* IfRing(Node* list){Node* slow = list;Node* fast = list;while (fast&&fast->next)      {slow = slow->next;   //慢指针一次走一步fast = fast->next->next;//快指针一次走两步if (slow==fast){return fast;   //fast追上slow时返回快指针}}return NULL;  //表示fast->next为空,链表不带环}
(2)求环的长度

求环的长度只需在第一次的相遇点开始,快慢指针继续走,当再次相遇时,走过的次数即使长度

int Length(Node* list){Node* fast = IfRing(list);if (fast){Node* slow = fast;int count = 0;while (fast&&fast->next){slow = slow->next;fast = fast->next->next;++count;if (slow == fast){return count;}}return 0;}}
(3)求环的入口



Node* Entry(Node* list){Node* fast = IfRing(list);//fast代表交点开始走Node* cur = list;//cur从最开始的结点走while (fast&&fast->next){cur = cur->next;fast = fast->next;if (fast == cur)  //相遇时代表走到了入口点{return fast;}}return NULL;}

2.判断两个链表是否相交,若相交,求交点。(假设链表不带环) 


求两个链表的相交点:


代码

ListNode* IfCoverge(ListNode** list1, ListNode** list2)//返回值是环内相遇点 判断是否相交(链表不带环){
       //让一个链表的尾指向另外一个链表的头,若有交点,则会形成环if (*list1 == NULL)return NULL;if (*list2 == NULL)return NULL;ListNode* cur1 = *list1;ListNode* cur2 = *list2;while (cur1->_next){cur1 = cur1->_next;}while (cur2->_next){cur2 = cur2->_next;}if (*list1 == *list2)return *list1;else if (cur1 == cur2)return cur1;else{cur2->_next = *list1;IfRing(*list2);  //调用之前的判断是否带环的函数。返回值值快慢指针的相遇的点}}


ListNode* Coverge(ListNode* list1,ListNode* list2)//两个链表交点(可能也是环入口点){                              //已知两个链表相交,则长的链表先走K步,K(size1-size2).之后两个链表同时走,相遇点就是交点ListNode* cur1 = list1;ListNode* cur2 = list2;size_t size1 = Size(list1);size_t size2 = Size(list2);if (size1 > size2){size_t k = size1 - size2;while (k--){cur1 = cur1->_next;}}else{size_t k = size2 - size1;while (k--){cur2 = cur2->_next;}}while (1){if (cur1==cur2)return cur1;cur1 = cur1->_next;cur2 = cur2->_next;}}

3 判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】 



1 两个链表都不带环

(1)没有交点  (2)有一个交点


2 一个链表带环,一个不带环

 (3)没有交点


3 两个链表都带环

 (4)没有交点   (5)有一个交点(交点有可能是入口点)    (6)有两个交点

ListNode* Node(ListNode* list1, ListNode* list2){ListNode* ret1 = Ret(list1);ListNode* ret2 = Ret(list2);if (!ret1&&!ret2)    //1 -两个链表都不带环{ListNode* point = IfCoverge(&list1, &list2);if (point == NULL){return NULL;    //1-1 没有交点}return Coverge(list1, list2); //1-2 一个交点  }else if ((!ret1&&ret2) || (ret1&&!ret2))  //2 一个带环一个不带环{return NULL;}else               // 3 两个都带环 {//1-两个环不相交//2-两个环的入口点相同//3-两个环相交且有两个交点if (ret1 == ret2)  //  3--2  入口点相同{ret1->_next = NULL;ret2->_next = NULL;Coverge(list1, list2);}else{ListNode* tmp = ret1->_next;while (tmp != ret1&&tmp != ret2){tmp = tmp->_next;}if (tmp == ret1){printf("两个链表分别带环,但不相交\n");return NULL;      //3-1 没有交点}printf("有两个交点\n");      //3-3 有两个交点printf(" %d\n", ret1->_data);return ret2;}}}











原创粉丝点击