寻找循环链表的循环起始点

来源:互联网 发布:ibm服务器安装linux 编辑:程序博客网 时间:2024/05/22 16:57
// 寻找循环链表的循环起始点

#include 
<stdio.h>
#include 
<stdlib.h>

// 算法:
//1. 判断链表中是否存在环
//2. 通过相遇点求环的长度Y,求链表起点到相遇点的距离L
//3. p1从距链表起点出发,p2从距相遇点Y-L%Y处出发,比较地址,
//     相等时即为循环起始点

struct Node
{
    
int data;
    Node 
*next;
}
;

int main()
{
    
// 初始化链表
    
//int List[] = {0,1,2,3,4,5,6,7,8,3};
    Node *head = NULL, *p, *q;
    
/*head = new Node;
    head->data = 0;
    head->next = NULL;
*/

    
int i;
    
for (i=8; i>=0--i)
    
{
        p 
= new Node;
        p
->data = i;
        p
->next = head;
        head 
= p;
    }


    
while(p->next!=NULL)
    
{
        printf(
"%d ", p->data);
        p 
= p->next;
    }

    printf(
"%d ", p->data);
    p
->next = head->next->next->next;
    p 
= head;

    
// 打印已初始化链表
    /*for (int i = 20; i>0; --i)
    {
        printf("%d ", p->data);
        p = p->next;
    }
*/


    
// 判断是否有环
    bool bCircle = false;
    p 
= q = head;
    
while(p!=NULL && q!=NULL && q->next!=NULL)
    
{
        p 
= p->next;
        q 
= q->next->next;
        
if (p == q)
        
{
            bCircle 
= true;
            
break;
        }

    }

    
    
if (!bCircle)
    
{
        printf(
"%s""The List has no circle.");
        
return 0;
    }


    
// 求链表起点到相遇点距离,求环的长度
    int L=0, Y=0, I = 0;;
    Node 
*interNode = p;    // 相遇点

    
for (p=head; p!=interNode; p=p->next)
        
++L;

    
for (Y=1,q=interNode->next; q!=interNode; q=q->next)
        
++Y;

    printf(
" L = %d, Y = %d ", L, Y);

    
//for (i=0, p=head; i<L/Y*Y; ++i)
    
//    p=p->next;

    
for (i=0, q=interNode; i<(L-L%Y); ++i)
        q
=q->next;

    
for (p=head; p!=q; p=p->next, q=q->next)
        
++I;
    
    printf(
"Length: %d, data: %d", I, p->data);
    getchar();
    
return 0;
}
 
原创粉丝点击