单链表的补充操作
来源:互联网 发布:剑三怎么下载捏脸数据 编辑:程序博客网 时间: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);// 判断链表是否相交,注意:链表可能带环
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.cvoid 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
- 单链表的补充操作
- 关于AD的操作 --补充
- 数据结构(5)之单链表的操作(补充)
- 单链表之操作补充_legend
- 关于AD的操作 -- 接口补充
- Python 文件IO操作的补充说明
- 关于定时器操作的一些补充
- iOS性能优化的一些操作(补充)
- 线程的基本操作(后续补充)
- Swift3.1 字符串的操作(补充)
- Groovy中对xml的操作补充
- 关于TensorFlow的padding操作是如何补充0 的
- String 基本操作补充
- java文件操作(补充)
- C#操作EXCEL补充
- sqlite基本操作补充
- Linux命令操作补充
- asp操作access数据库的读写删 补充:
- 微信公众平台开发教程(五)自定义菜单
- JAVA concurrent包学习--Exchanger
- jquery Dom操作方法简单归纳
- 安卓单选按钮值获取的两种方法
- 快学Scala(4) 映射和元组
- 单链表的补充操作
- 对于携带请求参数的HttpGet与的HttpPost两种请求方式,代码段分析
- 配置libjpeg库和png+zlib库
- 去除android studio 2.2.3 Rendering Problems
- Java基础 -- 枚举使用
- 6.java IO流学习
- Linux shell编程之grep命令
- 关于 Navicat for mysql 乱码的处理
- 神经网络2. epoch, iteration, batchsize相关理解和说明