单向链表中循环的查找方法总结
来源:互联网 发布:mysql高级编程 编辑:程序博客网 时间:2024/06/09 22:50
一个单向链表中可能存在循环,如何判断单向链表中是否存在循环,又如何找到循环部分的起始节点?如果是非循环链表,如何找到中间节点?
本文结合网上找到的资料及自己的分析,进行了总结。
链表节点定义如下:
typedef struct _node
{
int data;
struct _node *next;
}node,*pnode;
1、判断单向链表中是否存在循环链表
思路:设置两个指针,初始值都指向头节点,然后开始遍历,一个指针每次走一步,另一个指针每次走两步,如果存在循环链表,这两个链表肯定能相遇
代码:
//返回0表示没有循环
//返回1表示有循环
int FindLoop(node *head)
{
node *pOneStep, *pTwoStep;
int iReturn = 0;
if (NULL == head)
return 0;
pOneStep = head;
pTwoStep = head;
while ((NULL!=pTwoStep)&&(NULL!=pTwoStep->next))
{
pOneStep = pOneStep->next;
pTwoStep = pTwoStep->next->next;
if (pTwoStep == pOneStep)
return 1;
}
return 0;
}
2、找到单向非循环链表的中间节点
注意,是非循环链表
思路:设置两个指针,初始值都指向头节点,然后开始遍历,一个指针每次走一步,另一个指针每次走两步,走两步的指针到链表末尾时,走一步的指针刚好就指向了中间节点
代码:
node* FindNoLoopListMiddleNode(node *head){
node *pOneStep, *pTwoStep;
if (NULL == head || NULL==head->next)
return head;
pOneStep = head;
pTwoStep = head;
while ((NULL != pTwoStep) && (NULL != pTwoStep->next))
{
pTwoStep = pTwoStep->next->next;
if (NULL != pTwoStep)
pOneStep = pOneStep->next;
}
return pOneStep;
}
3、查找单向循环链表中的循环部分的起始节点
方法一:
首先用判断单向链表中是否存在循环链表的思路到达相遇节点,然后设置两个指针,分别从相遇节点和头节点单步进行遍历,两个指针相遇的节点就是循环的起始节点
关于这个思路的详细解释请自行查询或参考链接:http://www.cnblogs.com/cyttina/archive/2012/10/28/2743760.html
//寻找环的入口点NodeList FindLoopPort(NodeList head){ NodeList slow=head,fast=head; //得到相遇点 while(fast && fast->next) { slow=slow->next; fast=fast->next->next; if(slow==fast) break; } if(fast==NULL||fast->next==NULL) return NULL; //slow指向开头,fast在相遇点 //得到入口点 slow=head; while(slow!=fast){ slow=slow->next; fast=fast->next; } return slow;}
方法二:
思路: 设置两个指针 p1和p2,用p2遍历整个链表,用p1遍历p2走过的节点,当p1等于p2->next时,p1就是循环部分的起始节点。
这种方法与第一种方法相比,理解起来会简单很多,但算法复杂度有所提高。
代码:
//没有循环返回NULL
//如果存在循环返回循环起始节点的指针
node* FindLoopNode(node *head)
{
node *pc = head;
node *pf = NULL;
if (!pc)
return NULL;
while (pc)
{
pf = head;
while(pf && pf != pc)
{
//当前结点的下一个结点是它前面的某个结点或者是它自己,则为循环处
if (pc->next == pf || pc->next == pc)
return pc->next;
pf = pf->next;
}
pc = pc->next;
}
return NULL;
}
- 单向链表中循环的查找方法总结
- 两种方法实现单向链表的创建、遍历、删除、查找、逆序输出(循环法和递归法)
- 单向链表的插入、查找和遍历方法 (c)
- 二分查找的循环和递归方法
- 单向链表,单向循环链表的基本操作
- C——(单向、单向循环、双向、双向循环)链表学习总结
- 如何判断一个单向链表是否存在循环的经典方法
- 自己用的循环遍历查找List的方法
- 单向循环链表的建立
- 单向循环链表的C++实现
- 单向循环链表的合并图解
- 单向循环链表的应用
- android单向无限循环的轮播图效果。
- 带头结点的循环单向链表
- 单向循环链表的操作
- 带表头的单向循环链表
- 循环单向链表的相关算法
- 中间带环的单向循环链表
- ViewPager的用法
- JVM(10)--stackoverflow实战
- Java中字符串String Switch的实现原理
- 自绘控件的屏幕适配实现方法及实现装置
- MongoDB基本管理命令
- 单向链表中循环的查找方法总结
- linux快捷登录一 公钥拷贝
- 泉水——深搜
- Apriori算法代码及实例
- hibernate查询
- Maven3路程(三)用Maven创建第一个web项目(1)
- libpng warning: iCCP: Not recognizing known sRGB profile that has been edited
- 【Redis源码剖析】 - Redis数据类型之列表List
- C#第五次上机