单向链表中循环的查找方法总结

来源:互联网 发布: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;
}

0 0
原创粉丝点击