C语言实现单链表面试题--进阶

来源:互联网 发布:java nio长连接实现 编辑:程序博客网 时间:2024/06/13 05:34

1. 判断单链表是否带环?若带环,求环的长度?求环的入口点?

1.先判断链表是否带环,用快慢指针的方式,快指针pFast,慢指针pSlow;pFast快指针每次向后遍历两次,慢指针pSlow每次向后遍历一次,如果pFast会为NULL,说明链表不带环,否则说明带环同时会有:pFast==pSlow,因为在pSlow进入环后,pFast距pSlow的距离就会每次减一,直至相遇

这里写图片描述

//判断是否带环,若带环返回(!NULL),若不带环返回NULLListNode* ListRing(ListNode *pList){    if((pList == NULL)||(pList->next == NULL))        return NULL;    ListNode *pFast = pList;    ListNode *pSlow = pList;    while(pFast&&pFast->next)    {        pFast = pFast->next->next;        pSlow = pSlow->next;        if(pFast == pSlow)            return pFast;//返回快指针和慢指针的相遇点    }    return NULL;}
2.求入环点:一个指针从头指针开始遍历,一个指针从快慢指针相遇的指针处开始遍历,两个指针的相遇点就是入环点L:表示从头指针到入环点的距离X:表示慢指针在环内走的距离C:表示环的长度N:表示快指针在慢指针进入环区前绕环的圈数可知:快指针每次走两个节点,慢指针每次走一个节点,即快指针走的距离是慢指针的2倍; 

这里写图片描述

//求出带环链表的入口点ListNode* ListPoint(ListNode *pList, ListNode* Point),//Point 在判断是否带节点时的返回值{    while(pList != Point)    {        pList = pList->next;        Point = Point->next;    }    return Point;}
  3.求环的长度  从入环点开始遍历,到入环点就是环的长度
int ListLong(ListNode*Point)//求环的长度Point是入环点{    ListNode* cur = Point->next;    int i = 1;    while(cur != Point)    {        cur = cur->next;        i++;    }    return i;}

2.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)

两个链表的可能:
这里写图片描述

ListNode* ListPointNode(ListNode *pList_1, ListNode *pList_2)//判断两个链表是否相交,若相交返回相交点{    ListNode* JudgeRing_1 =  ListRing(pList_1);    ListNode* JudgeRing_2 =  ListRing(pList_2);//求链表是否带环,若不带环返回NULL    ListNode *cur_1 = pList_1;    ListNode *cur_2 = pList_2;    int i = 0;    int j = 0;    //情况1,4:两个链表都是没有环    if((JudgeRing_1 == NULL)&&(JudgeRing_2 ==NULL))    {        while(cur_1->next)        {            i++;            cur_1 = cur_1->next;        }        while(cur_2->next)        {            j++;            cur_2 = cur_2->next;        }        if(cur_1 != cur_2)//情况 1,            return NULL;        else//情况4        {            cur_1 = pList_1;             cur_2 = pList_2;             if(i>j)            {                int n = i-j;                while(n--)                {                    cur_1 = cur_1->next;                }            }            else            {                int n = j-1;                while(n--)                {                    cur_2 = cur_2->next;                }            }            while(cur_1 != cur_2)            {                cur_1 = cur_1->next;                cur_2 = cur_2->next;            }            return cur_1;//        }    }    else if((JudgeRing_1 != NULL)&&(JudgeRing_2 !=NULL))//    {        ListNode* Point_1 = ListPoint(pList_1, JudgeRing_1);//求链表的入空点        ListNode* Point_2 = ListPoint(pList_2, JudgeRing_2);        if(Point_1 == Point_2)//情况5        {            cur_1 = pList_1;             cur_2 = pList_2;             int i = 0;            int j = 0;            while(cur_1 != Point_1)            {                i++;                cur_1 = cur_1->next;            }            while(cur_2 != Point_1)            {                j++;                cur_2 = cur_2->next;            }            cur_1 = pList_1;             cur_2 = pList_2;            if(i>j)            {                int n = i-j;                while(n--)                {                    cur_1 = cur_1->next;                }            }            else            {                int n = j-1;                while(n--)                {                    cur_2 = cur_2->next;                }            }            while(cur_1 != cur_2)            {                cur_1 = cur_1->next;                cur_2 = cur_2->next;            }            return cur_1;        }        cur_1 = Point_1->next;         while(cur_1 != Point_1)        {            //情况6,交点在环上,返回其中一个的入口点            if(cur_1 == Point_2)                return  Point_1;            cur_1 = cur_1->next;        }        //情况3,两个带环链表没有交点        return NULL;    }    else //情况2;一个链表有环,一个没有环    {        return NULL;    }}
原创粉丝点击