判断一个单向链表中是否有环

http://blog.sina.com.cn/s/blog_5dc7bbf80100v77b.html

//判断一个单向链表中是否有环C面试算法解析
//
#include<stdio.h>
#include<stdlib.h>

typedef char elemtype;

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

Node* CreateList(int n)//构造包含n个节点的链表
{
    Node* p = (Node*)malloc(sizeof(Node));
    Node* head;
    
    head = p;
    head->data = 'A';
    
    for(char i = 'B'; i < 'A' + n; i++)
    {
        p = (p->next = (Node*)malloc(sizeof(Node)));
        p ->data = i;
        p ->next = NULL;
    }
    
    return head;
}

void Print(Node *head)
{
    static int i=0;
    for(Node* p = head; p ;p = p->next )
    {
        printf("%c->",p->data);
        if (++i % 10 ==0 )
        {
            printf("\ni=%d:Press Any Key to continue...\n",i);
            getchar();
        }
    }
    printf("\n");

}


void AddCircle(Node* head,int n)//将链表的末尾连接到链表的第n个节点的位置
{
    Node* p = head;
    Node* q = NULL;
    
    for(int i = 1;p->next ;i++)
    {
        if( i == n)
            q = p;
        p = p->next ;
    }
    p->next = q;
}

int TestList(Node* head)
{
    Node* p = head;
    Node* q = head;
    
        //printf("::p=%c,q=%c\n",p->data,q->data);
        //getchar();

    while(p ->next && q->next)//设置两个指针,一个指针的运动速度快于另一个指针的运动速度,那么两个总会有相遇的机会(如果存在环)。
    {
        p = p->next;
        if(NULL == (q = (q->next ->next)))
            return 0;

        //printf("while::p=%c,q=%c\n",p->data,q->data);
        //getchar();

        if(p == q)
            return 1;


    }
    return 0;
}

int main(int argc,char* argv[])
{
    Node* head = CreateList(9);//创建含有6个节点的单向链表
    Print(head);
    //return 0;
    AddCircle(head,5);//将链表的末尾指针指向链表的第5个节点,形成环,以便测试
    //Print(head);
    //return 0;
    //
    char *p = (TestList(head)) ? "该单向链表中存在环!" : "该单向链表中不存在环!";
    
    printf("%s\n",p);
    
    return 0;
}

 

posted @ 2018-03-30 16:20  sky20080101  阅读(143)  评论(0)    收藏  举报