#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<assert.h> typedef int DataType; typedef struct SListNode { DataType data; struct SListNode *next; }SListNode; void PrintFromEndToTail(SListNode * &Head);// 从尾到头打印。 void SListNodeReverse(SListNode *& Head); void Joseph(SListNode *&Head, DataType k); SListNode *Find(SListNode *Head, DataType x); void PushBack(SListNode * & Head);//尾插 SListNode *BuyNode(DataType x); void PrintSListNode(SListNode *Head); void BubbleSort(SListNode *&Head); //单链表排序(冒泡) SListNode *MergeList(SListNode *&Head1, SListNode *&Head2);//合并两个有序列表,合并后依然有序 //判断单链表是否带环?若带环求环长度?求环得入口点?并计算每个算法的时间复杂度和空间复杂度。 SListNode *CycleOrNot(SListNode *Head); int CycleLength(SListNode *meeting); SListNode *Entrance(SListNode *Head,DataType length); SListNode *FindCrossingNode(SListNode *Head1, SListNode *Head2);//判断两个链表是否相交,若相交,求交点(带环) int GetNodeCountOfList(SListNode *Head); SListNode *FindCycleEntry(SListNode Head); SListNode *FindLoopPort(SListNode *Head1, SListNode *Head2);//判断两个链表是否相交,若相交,求交点(不带环) //复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随即节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。 SListNode *BuyNode(DataType x) { SListNode *tmp = (SListNode*)malloc(sizeof(SListNode)); tmp->data = x; tmp->next = NULL; return tmp; } SListNode *Find(SListNode *Head, DataType x) { assert(Head); SListNode *cur = Head; while (cur) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } void PushBack(SListNode * & Head,DataType x) { if (Head == NULL) { Head = BuyNode(x); } else if (Head->next == NULL) { Head->next = BuyNode(x); } else { SListNode *tail = Head; while (tail->next != NULL) { tail = tail->next; } tail->next = BuyNode(x); } } void PrintSListNode(SListNode *Head) { if (Head == NULL) { return; } else { while (Head) { printf("%d ", Head->data); Head = Head->next; } } } void PrintFromEndToTail(SListNode * &Head) // 从尾到头打印。 { if (Head != NULL) { PrintFromEndToTail(Head->next); printf("%d ", Head->data); } } // 在无头链表的一个非头节点前插入一个节点 void InsertUheadPrev(SListNode * pos,DataType x)// 在无头链表的一个非头节点前插入一个节点 { assert(pos); SListNode * tmp = BuyNode(pos->data); SListNode *tmp2 = pos->next; pos->data = x; pos->next = tmp; tmp->next = tmp2; } //查找单链表的中间节点,要求只遍历一遍 SListNode *FindMidNode(SListNode *Head) { int i = 0; SListNode *fast = Head; SListNode *slow = Head; while (fast) { if (fast->next != NULL) { fast = fast->next->next; } else { return slow; } slow = slow->next; } return slow; } //查找单链表的倒数第K个节点,要求只遍历一遍 SListNode *FindKNode(SListNode *Head, DataType k) { int i = 0; SListNode *fast = Head; SListNode *slow = Head; for (i = 0; i < k; i++) { fast = fast->next; if (fast == NULL) { return NULL; } } while (fast) { fast = fast->next; slow = slow->next; } return slow; } //逆置或反转单链表 void SListNodeReverse(SListNode *& Head) { SListNode *pNode = Head; SListNode *Prev = NULL; SListNode *pNext = NULL; while ( pNode) { pNext = pNode->next; if (pNext) { Head = pNode->next; } pNode->next = Prev; Prev = pNode; pNode = pNext; } } // 删除一个无头链表的非尾节点 void SListDel(SListNode *&del) { SListNode *tmp = del->next->next; del->data = del->next->data; del->next = tmp; free(del->next); } void Joseph(SListNode *&Head, int k) { assert(Head); SListNode* cur = Head; SListNode *del = NULL; while (1) { if (cur->next == cur) { printf("%d", cur->data); return; } for (int i = 1; i < k; i++) { cur = cur->next; } del = cur->next; cur->data = cur->next->data; cur->next = del->next; free(del); } } void BubbleSort(SListNode *&Head) //冒泡排序 { SListNode *tail = NULL; while (Head->next != tail) { int flag = 0; SListNode *cur = Head; SListNode *CurNext = cur->next; while (cur->next!=tail) { if (cur->data > CurNext->data) { DataType tmp = cur->data; cur->data = CurNext->data; CurNext->data = tmp; flag = 1; } cur = cur->next; CurNext = CurNext->next; } tail = cur; if (flag == 0) { return; } } } SListNode *MergeList(SListNode *&Head1, SListNode *&Head2) //合并两个有序列表,合并后依然有序 { SListNode *cur1 = Head1; SListNode *cur2 = Head2; SListNode *tmp = NULL; SListNode *NewHead = NULL; if (cur1->data > cur2->data) { NewHead = cur2; cur2 = cur2->next; } else { NewHead = cur1; cur1 = cur1->next; } tmp = NewHead; while (cur1 && cur2) { if (cur1->data >= cur2->data) { tmp->next = cur2; tmp = cur2; cur2 = cur2->next; } else { tmp->next = cur1; tmp = cur1; cur1 = cur1->next; } } if (cur1) { tmp->next = cur2; return NewHead; } else { tmp->next = cur1; return NewHead; } } //判断单链表是否带环?若带环求环长度?求环得入口点?并计算每个算法的时间复杂度和空间复杂度。 SListNode *CycleOrNot(SListNode *Head) { assert(Head); SListNode *fast = Head; SListNode *slow = Head; while (fast) { fast = fast->next->next; slow = slow->next; if (fast == slow) { printf("此单链表带环\n"); return fast; } } return NULL; } int CycleLength(SListNode *meeting) { assert(meeting); SListNode *tmp = meeting; int count = 1; while (1) { tmp = tmp->next; if (tmp == meeting) { return count; } count++; } } SListNode *Entrance(SListNode *Head, DataType length) { assert(Head); SListNode *fast = Head; SListNode *slow = Head; while (length--) { fast = fast->next; } while (1) { fast = fast->next; slow = slow->next; if (fast == slow) { return fast; } } return NULL; } SListNode *FindLoopPort(SListNode *Head1, SListNode *Head2) { assert(Head1); assert(Head2); SListNode *cur1 = Head1; SListNode *cur2 = Head2; SListNode *ret = NULL; int length1 = 1; int length2 = 1; int count = 0; int flag = 0; while (cur1) { cur1 = cur1->next; length1++; } while (cur2) { cur2 = cur2->next; length2++; } if (cur1 != cur2) { printf("NO Port!\n"); return NULL; } else { if (length1 > length2) { count = length1 - length2; flag = 1; } else { count = length2 - length1; } if (flag == 0) { cur1 = Head1; cur2 = Head2; while (count--) { cur2 = cur2->next; } while (cur1 && cur2) { cur1 = cur1->next; cur2 = cur2->next; if (cur1 == cur2) { return cur1; } } } else { cur1 = Head1; cur2 = Head2; while (count--) { cur1 = cur1->next; } while (cur1 && cur2) { cur1 = cur1->next; cur2 = cur2->next; if (cur1 == cur2) { return cur1; } } } } return NULL; } //1、是否相交于环外,使用指针追赶的方法 //2、若不满足情况1,即不相交于环外,但两个链表又相交,则肯定相交于环内。 SListNode *FindCrossingNode(SListNode *Head1, SListNode *Head2) { assert(Head1); assert(Head2); SListNode *cur1 = Head1; SListNode *cur2 = Head2; int count1 = GetNodeCountOfList(Head1); int count2 = GetNodeCountOfList(Head2); SListNode *enter1 = FindCycleEntry(Head1); SListNode *enter2 = FindCycleEntry(Head2); while (count1 - count2 > 0) { cur1 = cur1->next; count1--; } while (count2 - count1> 0) { cur2 = cur2->next; count2--; } while (cur1 != enter1 && cur2 != enter2 && cur1 != cur2) { cur1 = cur1->next; cur2 = cur2->next; } if (cur1 != cur2) //交点在环中 { return enter1; } else //交点在环内 { return cur1; } } //1、先找到碰撞点 //2、利用碰撞点,找到环入口点,同时统计第一个结点到碰撞点之间结点个数 //3、利用碰撞点或者环入口点,在环中转圈,统计环中结点个数 int GetNodeCountOfList(SListNode *Head) { assert(Head); SListNode *fast = Head; SListNode *slow = Head; SListNode *enter = Head; int CountEnter = 0; int CountCycle = 1; while (fast->next->next) { slow = slow->next; fast = fast->next->next; if (fast == slow) { while (enter != slow) //查找环的入口结点,并统计第一个结点到碰撞点之间结点个数 { enter = enter->next; slow = slow->next; CountEnter++; } slow = fast; fast = fast->next; while (fast != slow) { fast = fast->next; CountCycle++; } return CountCycle + CountEnter; } } return 0; } /*在快慢指针相遇处,使用两个指针分别从头结点和碰撞处开始走,相遇点就是环入口点*/ SListNode *FindCycleEntry(SListNode *Head) { assert(Head); SListNode* fast=Head; SListNode *slow=Head; SListNode *enter = Head; while (1) { fast = fast->next->next; slow = slow->next; if (fast == slow) { while (slow != enter) { slow = slow->next; enter = enter->next; } return enter; } } return NULL; } void Test1() { SListNode *Head = NULL; PushBack(Head, 1); PushBack(Head, 2); //PushBack(Head, 3); //PushBack(Head, 4); //PushBack(Head, 5); PrintFromEndToTail(Head); } void Test2() { SListNode *Head = NULL; PushBack(Head, 1); PushBack(Head, 2); PushBack(Head, 3); PushBack(Head, 4); PushBack(Head, 5); SListNodeReverse(Head); PrintSListNode(Head); } void Test3() //约瑟夫环 { SListNode *Head = NULL; PushBack(Head, 1); /*PushBack(Head, 2);*/ //PushBack(Head, 3); //PushBack(Head, 4); //PushBack(Head, 5); //PushBack(Head, 6); SListNode *tail = Find(Head, 1); tail->next = Head; Joseph(Head, 3); } void Test4() { SListNode *Head = NULL; PushBack(Head, 1); PushBack(Head, 4); PushBack(Head, 5); PushBack(Head, 3); PushBack(Head, 2); BubbleSort(Head); PrintFromEndToTail(Head); } void Test5() { SListNode *Head1 = NULL; SListNode *Head2 = NULL; PushBack(Head1, 1); PushBack(Head1, 3); PushBack(Head1, 5); PushBack(Head1, 7); PushBack(Head1, 9); PushBack(Head2, 2); PushBack(Head2, 4); PushBack(Head2, 6); PushBack(Head2, 8); PushBack(Head2, 10); SListNode *NewHead=MergeList(Head1, Head2); PrintSListNode(NewHead); } void Test6() //带环问题 { SListNode *Head = NULL; PushBack(Head, 1); PushBack(Head, 4); PushBack(Head, 5); PushBack(Head, 3); PushBack(Head, 2); PushBack(Head, 9); PushBack(Head, 2); PushBack(Head, 4); PushBack(Head, 6); SListNode *tmp1 = Find(Head, 9); SListNode *tmp2=Find(Head, 6); tmp2->next = tmp1; SListNode *meeting=CycleOrNot(Head); int length=CycleLength(meeting); SListNode *ret=Entrance(Head, length); printf("%d\n", ret->data); printf("%d", length); } void Test7() { SListNode *Head1 = NULL; SListNode *Head2 = NULL; PushBack(Head1, 1); PushBack(Head1, 3); PushBack(Head1, 5); PushBack(Head1, 7); PushBack(Head1, 9); PushBack(Head2, 2); PushBack(Head2, 4); PushBack(Head2, 6); PushBack(Head2, 8); PushBack(Head2, 10); SListNode *tmp1 = Find(Head1, 5); SListNode *tmp2 = Find(Head2, 10); tmp2->next = tmp1; SListNode *ret=FindLoopPort(Head1, Head2); printf("%d", ret->data); } int main() { //Test1(); /*Test2();*/ /*Test3();*/ Test7(); system("pause"); }