单链表的补充操作

来源:互联网 发布:剑三怎么下载捏脸数据 编辑:程序博客网 时间:2024/06/07 23:09

约瑟夫环约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依规律重复下去,直到圆桌周围的人全部出列。

算法原理:约瑟夫环运作如下:
1、一群人围在一起坐成[2]  环状(如:N)
2、从某个编号开始报数(如:K)
3、数到某个数(如:M)的时候,此人出列,下一个人重新报数
4、一直循环,直到所有人出列[3]  ,约瑟夫环结束

voidJosephCircle(PNode*pHead,size_tM); //约瑟夫环

 

voidInsertNotHead(PNodepos,DataTypedata);//在单链表非头结点前插入结点data

 

voidPrintFromTail2Head(PNodepHead);//使用递归实现从未到头打印单链表

 

voidDeleteNotTailNode(PNodepos);//删除单链表的非尾结点

 

PNodeFindMidNode(PNodepHead);//查找单链表的中间结点,要求只便利一次链表

 

PNodeFindLastKNode(PNodepHead,size_tk);//查找单链表的倒数第K个结点,要求只遍历一次链表

 

voidBubbleSort(PNodepHead);//使用冒泡排序对单链表进行排序

 

int IsListCross(PNodeL1,PNodeL2);//判断两个单链表是否相交(链表不带环)

 

PNodeGetCrossNode(PNodePL1,PNodePL2);//若不带环的单链表相交,求交点


PNodeReverseList(PNodepHead);// 实现单链表的逆置:使用三个指针

 

voidReverseList_P(PNode*pHead);// 实现单链表的逆置:使用头插法

 

PNodeMergeList(PNodepHead1, PNodepHead2);// 合并两个已序单链表,合并后依然有序

 

PNodeHasCircle(PNodepHead);// 判断链表是否带环,若带环给出相遇点

 

size_t GetCircleLen(PNodepMeetNode);//求环的长度

 

PNodeGetEnterNode(PNodepHead, PNodepMeetNode);// 求环的入口点

 

int IsCrossWithCircle(PNode pHead1, PNode pHead2);// 判断链表是否相交,注意:链表可能带环

List.h

#include <stdlib.h>#include <assert.h>#include <stdio.h>typedef int DataType;typedef struct Node{DataType _data;struct Node* _pNext;}Node, *PNode;void JosephCircle(PNode *pHead, size_t M); //约瑟夫环void InsertNotHead(PNode pos, DataType data);// 在单链表非头结点前插入结点datavoid PrintFromTail2Head(PNode pHead);// 使用递归实现从未到头打印单链表void DeleteNotTailNode(PNode pos);// 删除单链表的非尾结点PNode FindMidNode(PNode pHead);// 查找单链表的中间结点,要求只便利一次链表PNode FindLastKNode(PNode pHead, size_t k);// 查找单链表的倒数第K个结点,要求只遍历一次链表void BubbleSort(PNode pHead);// 使用冒泡排序对单链表进行排序int IsListCross(PNode L1, PNode L2);// 判断两个单链表是否相交(链表不带环)PNode GetCrossNode(PNode PL1, PNode PL2);// 若不带环的单链表相交,求交点PNode ReverseList(PNode pHead);// 实现单链表的逆置:使用三个指针void ReverseList_P(PNode* pHead);// 实现单链表的逆置:使用头插法PNode MergeList(PNode pHead1, PNode pHead2);// 合并两个已序单链表,合并后依然有序PNode HasCircle(PNode pHead);// 判断链表是否带环,若带环给出相遇点size_t  GetCircleLen(PNode pMeetNode);// 求环的长度PNode GetEnterNode(PNode pHead, PNode pMeetNode);// 求环的入口点int IsCrossWithCircle(PNode pHead1, PNode pHead2);// 判断链表是否相交,注意:链表可能带环


List.c

PNode Back(PNode pHead) // 返回单链表的最后一个结点的位置{if(pHead == NULL){return NULL;}else{Node* PTailNode = pHead;while(PTailNode->_pNext){PTailNode = PTailNode->_pNext;}return PTailNode;}}void JosephCircle(PNode *pHead, size_t M) //约瑟夫环{size_t m = 0;PNode PCurNode = NULL;PNode PTailNode = Back(*pHead);PTailNode->_pNext = *pHead;assert(pHead);if(*pHead == NULL || M == 1){return;}else{PNode PCurNode = *pHead;while(PCurNode->_pNext != PCurNode){PNode PDelNode = NULL;m = M;while(--m){PCurNode = PCurNode->_pNext;}PDelNode = PCurNode->_pNext;PCurNode->_data = PDelNode->_data;PCurNode->_pNext = PDelNode->_pNext;free(PDelNode);*pHead = PCurNode;}PCurNode->_pNext = NULL;        }}void InsertNotHead(PNode pos, DataType data) // 在单链表非头结点前插入结点data{PNode PpreNode = NULL;PNode PCurNode = NULL;if(pos == NULL || pos->_pNext == NULL){return;}PpreNode = BuyNode(pos->_data);PpreNode->_pNext = pos->_pNext;pos->_pNext = PpreNode;pos->_data = data;}PNode FindMidNode(PNode pHead) // 查找单链表的中间结点,要求只便利一次链表{PNode pFast = NULL;PNode pSlow = NULL;PNode pre = NULL;if(pHead == NULL || pHead->_pNext == NULL){return NULL;}else{pFast = pHead;pSlow = pHead;while((NULL != pFast) && (NULL != pFast->_pNext)){pFast = pFast->_pNext->_pNext;pre = pSlow;pSlow = pSlow->_pNext;}pSlow->_pNext = NULL;return pSlow; //偶数个的前一个中间节点/*if(pFast == NULL){pre->_pNext = NULL;return pre;}if(pFast->_pNext == NULL){pSlow->_pNext = NULL;return pSlow; //偶数个的后一个中间节点}*/}}PNode FindLastKNode(PNode pHead, size_t k) // 查找单链表的倒数第K个结点,要求只遍历一次链表{assert(pHead);if(k > Size(pHead)){return NULL;}else{PNode PreNode = pHead;PNode PCurNode = pHead;while(--k){PreNode = PreNode->_pNext;}while(PreNode->_pNext){PreNode = PreNode->_pNext;PCurNode = PCurNode->_pNext;}PCurNode->_pNext = NULL;return PCurNode;}}void BubbleSort(PNode pHead) // 使用冒泡排序对单链表进行排序   //降序{if(pHead == NULL || pHead->_pNext == NULL){return;}else{PNode pTailNode = NULL;PNode PpreNode = pHead;PNode PCurNode = PpreNode->_pNext;while(PCurNode != pHead){PpreNode = pHead;PCurNode = PpreNode->_pNext;while(PCurNode->_pNext != pTailNode){if(PCurNode->_data > PpreNode->_data){DataType tmp = PCurNode->_data;PCurNode->_data = PpreNode->_data;PpreNode->_data = tmp;}PpreNode = PpreNode->_pNext;PCurNode = PCurNode->_pNext;}pTailNode = PCurNode;PCurNode = PpreNode;}}}int IsListCross(PNode L1, PNode L2) // 判断两个单链表是否相交(链表不带环){if(L1 == NULL || L2 == NULL){return 0;}else{PNode pTailNode1 = L1;PNode pTailNode2 = L2;while(pTailNode1->_pNext){pTailNode1 = pTailNode1->_pNext;}while(pTailNode2->_pNext){pTailNode2 = pTailNode2->_pNext;}if(pTailNode2 == pTailNode1){return 1;}else{return 0;}}}PNode GetCrossNode(PNode PL1, PNode PL2) // 若不带环的单链表相交,求交点{if(PL1 == NULL || PL2 == NULL){return NULL;}else{if(!IsListCross(PL1, PL2)){return NULL;}else{size_t size1 = Size(PL1);size_t size2 = Size(PL2);int sz = size1 - size2;PNode pPre1 = PL1;PNode pPre2 = PL2;if(sz<0){    pPre1 = PL1;pPre2 = PL2;sz = -sz;while(sz--){pPre2 = pPre2->_pNext;}}else if(sz>0){    pPre1 = PL1;    pPre2 = PL2;while(sz--){pPre1 = pPre1->_pNext;}}while(pPre1->_pNext){if(pPre1 == pPre2){pPre1->_pNext = NULL;return pPre1;}pPre1 = pPre1->_pNext;pPre2 = pPre2->_pNext;}if(pPre2 == pPre1){pPre1->_pNext = NULL;return pPre1;}else {return NULL;}}}}
PNode ReverseList(PNode pHead)// 实现单链表的逆置:使用三个指针{PNode PreNode = NULL;PNode PCurNode = NULL;PNode PNextNode = NULL;if(pHead == NULL || pHead->_pNext == NULL){return NULL;}else{PreNode = pHead;PCurNode = PreNode->_pNext;PNextNode = PCurNode->_pNext;while(PCurNode->_pNext){PCurNode->_pNext = PreNode;PreNode = PCurNode;PCurNode = PNextNode;PNextNode = PNextNode->_pNext;}PCurNode->_pNext = PreNode;pHead->_pNext = NULL;pHead = PCurNode;return pHead;}}// 实现单链表的逆置:使用头插法void ReverseList_P(PNode* pHead){   PNode PNewNode = NULL;   PNode PreNode = NULL;   PNode PCurNode = NULL;   if(*pHead == NULL || (*pHead)->_pNext == NULL)   {   return;   }   PreNode = *pHead;   PCurNode = (*pHead)->_pNext;   while(PCurNode)   {   PreNode->_pNext = PNewNode;   PNewNode = PreNode;   PreNode = PCurNode;   PCurNode = PCurNode->_pNext;   }   PreNode->_pNext = PNewNode;   PNewNode = PreNode;   *pHead = PNewNode;   } //合并两个已序单链表,合并后依然有序PNode MergeList(PNode pHead1, PNode pHead2){if(pHead1 == NULL && pHead2 == NULL){return NULL;}else if(pHead1 == NULL || pHead2 == NULL){if(pHead2 == NULL){return pHead1;}else{return pHead2;}}else{PNode pH1 = pHead1;PNode pH2 = pHead2;PNode PNewNode = NULL;PNode TailNode = NULL;if(pH1->_data <= pH2->_data){PNewNode = pH1;pH1 = pH1->_pNext;}else{PNewNode = pH2;pH2 = pH2->_pNext;}TailNode = PNewNode;    while(pH1 && pH2){if(pH1->_data <= pH2->_data){PNewNode->_pNext = pH1;pH1 = pH1->_pNext;}else{PNewNode->_pNext = pH2;pH2 = pH2->_pNext;}PNewNode = PNewNode->_pNext;}if(pH1){PNewNode->_pNext = pH1;}else{PNewNode->_pNext = pH2;}return TailNode;}}// 判断链表是否带环,若带环给出相遇点PNode HasCircle(PNode pHead){if(pHead == NULL){return NULL;}else{PNode pFast = pHead;PNode pSlow = pHead;{while(pFast && pFast->_pNext){pSlow = pSlow->_pNext;pFast = pFast->_pNext->_pNext;if(pFast == pSlow){return pSlow;}}return NULL;}}}// 求环的长度size_t  GetCircleLen(PNode pMeetNode){PNode pCurNode = pMeetNode;size_t count = 1;while(pCurNode->_pNext != pMeetNode){pCurNode = pCurNode->_pNext;count++;}return count;}// 求环的入口点PNode GetEnterNode(PNode pHead, PNode pMeetNode){if(pHead == NULL){return NULL;}else {PNode pFast = pHead;PNode pSlow = pMeetNode;{while(pFast != pSlow){pSlow = pSlow->_pNext;pFast = pFast->_pNext;}return pSlow;}}}// 判断链表是否相交,注意:链表可能带环int IsCrossWithCircle(PNode pHead1, PNode pHead2){PNode pMeetNode1 = HasCircle(pHead1);PNode pMeetNode2 = HasCircle(pHead2);if(pHead1 == NULL || pHead2 == NULL){return 0;}else if(pMeetNode1 == NULL && pMeetNode2 == NULL){PNode pTailNode1 = pHead1;PNode pTailNode2 = pHead2;while(pTailNode1->_pNext){pTailNode1 = pTailNode1->_pNext;}while(pTailNode2->_pNext){pTailNode2 = pTailNode2->_pNext;}if(pTailNode2 == pTailNode1){return 1;}else{return 0;}}else if(pMeetNode1 && pMeetNode2){PNode pCurNode = pMeetNode1;while(pCurNode->_pNext != pMeetNode1){if(pCurNode == pMeetNode2){return 2;}pCurNode = pCurNode->_pNext;}return 0;}else{return 0;}}

test.c

void Test6(){Node *Node = NULL;InitList(&Node);PushBack(&Node, 1);PushBack(&Node, 2);PushBack(&Node, 3);PushBack(&Node, 4);PushBack(&Node, 5);PushBack(&Node, 6);PushBack(&Node, 7);PrintList(Node);JosephCircle(&Node, 3);PrintList(Node);}void Test7(){Node *Node = NULL;InitList(&Node);PushBack(&Node, 1);PushBack(&Node, 2);PushBack(&Node, 3);PushBack(&Node, 4);PushBack(&Node, 5);PushBack(&Node, 6);PushBack(&Node, 7);PrintList(Node);PrintFromTail2Head(Node);PrintList(Node);InsertNotHead(Find(Node, 5),8);PrintList(Node);}void Test8(){Node *Node = NULL;InitList(&Node);PushBack(&Node, 1);PushBack(&Node, 2);PushBack(&Node, 3);PushBack(&Node, 4);PushBack(&Node, 5);PushBack(&Node, 6);PushBack(&Node, 7);PrintList(Node);DeleteNotTailNode(Find(Node,4));PrintList(Node);}void Test9(){Node *Node = NULL;InitList(&Node);PushBack(&Node, 1);PushBack(&Node, 2);PushBack(&Node, 3);PushBack(&Node, 4);PushBack(&Node, 5);PushBack(&Node, 6);//PushBack(&Node, 7);PrintList(Node);PrintList(FindMidNode(Node));PrintList(FindLastKNode(Node, 3));}void Test10(){Node *Node = NULL;InitList(&Node);PushBack(&Node, 6);PushBack(&Node, 2);PushBack(&Node, 3);PushBack(&Node, 7);PushBack(&Node, 5);PushBack(&Node, 1);PrintList(Node);BubbleSort(Node);PrintList(Node);}void Test11(){Node *Node1 = NULL;Node *Node2 = NULL;Node *TailNode = NULL;int ret = 0;InitList(&Node1);InitList(&Node2);PushBack(&Node1, 1);PushBack(&Node1, 2);PushBack(&Node1, 3);PushBack(&Node1, 4);PushBack(&Node1, 5);PushBack(&Node1, 6);    PushBack(&Node2, 4);    PushBack(&Node2, 5);TailNode = Back(Node2);TailNode->_pNext = Find(Node1, 2);    ret = IsListCross(Node1, Node2);printf("%d\n", ret);TailNode = GetCrossNode(Node1, Node2);PrintList(TailNode);}
void Test12(){Node *Node = NULL;InitList(&Node);PushBack(&Node, 1);PushBack(&Node, 2);PushBack(&Node, 3);PushBack(&Node, 4);PushBack(&Node, 5);PushBack(&Node, 6);PrintList(Node);ReverseList_P(&Node);PrintList(Node);}void Test13(){Node *Node1 = NULL;Node *Node2 = NULL;Node *NewNode = NULL;InitList(&Node1);InitList(&Node2);PushBack(&Node1, 1);PushBack(&Node1, 1);PushBack(&Node1, 3);PushBack(&Node1, 4);PushBack(&Node1, 4);PushBack(&Node1, 6);PushBack(&Node2, 2);PushBack(&Node2, 2);PushBack(&Node2, 3);PushBack(&Node2, 4);PushBack(&Node2, 5);PushBack(&Node2, 5);NewNode = MergeList(Node1, Node2);PrintList(NewNode);}void Test14(){Node *Node1 = NULL;Node *Node2 = NULL;Node *TailNode = NULL;size_t ret = 0;InitList(&Node1);InitList(&Node2);PushBack(&Node1, 1);PushBack(&Node1, 2);PushBack(&Node1, 3);PushBack(&Node1, 4);PushBack(&Node1, 5);PushBack(&Node1, 6);TailNode = Back(Node1);TailNode->_pNext = Find(Node1, 2);    ret = GetCircleLen(HasCircle(Node1));TailNode = GetEnterNode(Node1, HasCircle(Node1));TailNode->_pNext = NULL;PrintList(TailNode);}void Test15(){Node *Node1 = NULL;Node *Node2 = NULL;Node *TailNode1 = NULL;Node *TailNode2 = NULL;size_t ret = 0;InitList(&Node1);InitList(&Node2);PushBack(&Node1, 1);PushBack(&Node1, 2);PushBack(&Node1, 3);PushBack(&Node1, 4);PushBack(&Node1, 5);PushBack(&Node1, 6);PushBack(&Node2, 0);PushBack(&Node2, 7);PushBack(&Node2, 9);PushBack(&Node2, 8);TailNode1 = Back(Node1);TailNode1->_pNext = Find(Node1, 4);TailNode2 = Back(Node2);TailNode2->_pNext = Find(Node1, 3);ret = IsCrossWithCircle(Node1, Node2);if(ret == 0){printf("这两个链表不相交\n");}if(ret == 1){printf("这两个不带环链表相交\n");}if(ret == 2){printf("这两个带环链表相交\n");}}

int main(){Test11();system("pause");return 0;}








0 0
原创粉丝点击