链表所有的相关操作(合并,查找,逆制,判环,相交)

来源:互联网 发布:结婚录像制作软件 编辑:程序博客网 时间:2024/05/20 13:36

1.合并两个有序链表,合并以后的链表依旧有序。

#pragma oncetypedef struct ListNode{int _data;ListNode* _next;}Node;void Display(Node* head)     //非递归打印{while (head){cout << head->_data << " ";head = head->_next;}cout << endl;}Node* MeageList(Node* l1, Node* l2) //合并链表{Node* NewNode = new Node;Node* cur1;Node* cur2;if (NULL == l1){return l2;}if (NULL == l2){return l1;}if (l1->_data < l2->_data)    //吧头数据小的一个作为新链表的头{NewNode->_data = l1->_data;cur1 = l1->_next;cur2 = l2;}else{NewNode->_data = l2->_data;cur2 = l2->_next;cur1 = l1;}Node* NewList = NewNode;while (cur1 && cur2)            //把剩余链表连接在后面{if (cur1->_data > cur2->_data){NewNode->_next = cur2;NewNode = NewNode->_next;cur2 = cur2->_next;}else{NewNode->_next = cur1;NewNode = NewNode->_next;cur1 = cur1->_next;}}if (cur1 == NULL){NewNode->_next = cur2;}elseNewNode->_next = cur1;return NewList;}Node* MeageListRe(Node* l1, Node* l2) // 递归合并{if (NULL == l1){return l2;}if (NULL == l2){return l1;}if (l1->_data < l2->_data){l1->_next = MeageListRe(l1->_next, l2);return l1;}else{l2->_next = MeageListRe(l2->_next, l1);return l2;}}

2.逆置/反转单链表,查找单链表的倒数第k个节点,要求只能遍历一次链表 。

typedef struct ListNode       //链表节点{int _data;ListNode* _next;}Node;Node* ReverceList(Node* list)    //逆制单链表   (取下一个节点,头插) {if (NULL == list){return NULL;}Node* Head = list->_next;  Node* NewHead = list; //原链表的头节点,变成新链表的尾节点。Node* cur = list->_next;NewHead->_next = NULL;while (cur){Head = cur;cur = cur->_next;Head->_next = NewHead;  //找到下一个节点,插在前面NewHead = Head;}return Head;}Node* ReFind(Node* list, int k)  //查找倒数第K个节点, (两指针 相差K-1步){if (NULL == list){return NULL;}Node* ptr1 = list;Node* ptr2 = list;while (k--){ptr1 = ptr1->_next;    //ptr1先走 k-1 步}while (ptr1&&ptr2)  {ptr1 = ptr1->_next;ptr2 = ptr2->_next;}return ptr2;}

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

typedef struct ListNode    //链表节点{int _data;ListNode* _next;}Node;Node* Find(Node* list, int key)  //查找某个节点{if (NULL == list)return NULL;Node* node = list;while (node){if (node->_data == key){return node;}node = node->_next;}return NULL;}Node* MakeRing(Node* list)      // 构建带环链表{Node* ret = Find(list, 9);Node* newnode = list;Node* newhead = list;while (newnode->_next){newnode = newnode->_next;}newnode->_next = ret;return newhead;}bool JudgeRing(Node* list)     //判断链表是否带环{if (NULL == list)return false;Node* fast = list;Node* slow = list;while (fast && fast->_next){fast = fast->_next->_next;slow = slow->_next;if (slow == fast)return true;}return false;}Node* FindRingnode(Node* list)     //找链表环的入口点{if (NULL == list)return NULL;Node* fast = list;Node* slow = list;while (fast && fast->_next){fast = fast->_next->_next;slow = slow->_next;if (slow == fast)break;}if (fast && fast->_next){slow = list;}elsereturn NULL;// 若带环 ,slow从头开始走,fast从相遇点开始走,第一次相遇即为交点while (slow != fast){slow = slow->_next;fast = fast->_next;}return slow;}int RingLong(Node* list)             //求环的长度{Node* node = FindRingnode(list); //找到还的入口点int count = 0;Node* node1 = node;while (node){node = node->_next;count++;if (node == node1)  //当在环内走一圈,走的距离就是环长break;}return count;}


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

typedef struct ListNode{int _data;ListNode* _next;}Node;Node* Find(Node* list, int key)  //查找结点{assert(list);Node* node = list;while (node){if (node->_data == key){return node;}node = node->_next;}return NULL;}Node* MakeRing(Node* list)       //建造带环链表{assert(list);Node* node = list;while (node->_next){node = node->_next;}node->_next = Find(list, 1);return list;}void MakeCrossList(Node* list1, Node* list2)      //建造相交链表{assert(list1);assert(list2);Node* node2 = list2;while (node2->_next){node2 = node2->_next;}node2->_next = Find(list1, 3);}bool JudgeRing(Node* list)     //判断链表是否带环{if (NULL == list)return false;Node* fast = list;Node* slow = list;while (fast && fast->_next)  //快慢指针是否相遇{fast = fast->_next->_next;slow = slow->_next;if (slow == fast)return true;}return false;}Node* FindRingnode(Node* list)     //找带环链表的入口点{if (NULL == list)return NULL;Node* fast = list;Node* slow = list;while (fast && fast->_next){fast = fast->_next->_next;slow = slow->_next;if (slow == fast)break;}if (fast && fast->_next){slow = list;}elsereturn NULL;// 若带环 ,slow从头开始走,fast从相遇点开始走,第一次相遇即为交点while (slow != fast){slow = slow->_next;fast = fast->_next;}return slow;}int RingLong(Node* list)             //求环的长度{Node* node = FindRingnode(list);int count = 0;Node* node1 = node;while (node){node = node->_next;count++;if (node == node1)break;}return count;}Node* JudgeCross1(Node* list1, Node* list2)   //不带环相交的判断{assert(list1);assert(list2);Node* head1 = list1;Node* head2 = list2;while (head2->_next){head2 = head2->_next;}head2->_next = head1;      //让 list1 的头链上 list2 的结尾//判断新链表是否带环//若新链表带环,则环的入口点就是第一个相交的点return FindRingnode(list2);}int GetListlength(Node* list)     //求链表长度{assert(list);Node* head = list;int len = 0;while (head){if (JudgeRing(list))      //带环链表的长{Node* node = FindRingnode(list);while (node != head){head = head->_next;len++;}len = len + RingLong(list);  //链表长 = 头结点到环入口的长度 + 环的长度break;}else      //不带环链表的长{len++;head = head->_next;}}return len;}Node* JudgeCross2(Node* list1, Node* list2)  //链表带环相交{//1.环外相交//2.环内相交assert(list1);assert(list2);int long1 = GetListlength(list1);int long2 = GetListlength(list2);int step = 0;Node* head1 = list1;Node* head2 = list2;if (long1 > long2)     //长的链表先走,让链表等长{step = long1 - long2;while (step--)head1 = head1->_next;}else{step = long2 - long1;while (step--)head2 = head2->_next;}if (JudgeRing(list1) && JudgeRing(list2)) //若相交,两条链表必然都带环{while (FindRingnode(list1) != head2){head2 = head2->_next;}if (head2 == FindRingnode(list1))  //若相交,list1 环上的点(入口点),必在 list2 上{while (head1 != FindRingnode(list1))  //1.环外相交 {head1 = head1->_next;head2 = head2->_next;if (head1 == head2)return head1;}if (head1 == FindRingnode(list1))  //2.环上相交(环有两个入口点),环的任意一个入口点就是交点return FindRingnode(list1);}elsereturn NULL;}return NULL;}

阅读全文
0 0
原创粉丝点击