链表的常见面试题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LYJwonderful/article/details/79958779
链表的基本操作

逆序打印单链表
删除链表的非尾结点,要求:不能遍历链表
在链表pos位置前插入值到data的结点
查找链表的中间结点,要求只能遍历一次链表
查找链表的倒数第K个结点,要求只能遍历一次链表
删除链表的倒数第K个结点,要求只能遍历一次链表
用单链表实现约瑟夫环
链表的逆置–三个指针
链表的逆置–头插法
用冒泡排序思想对单链表进行排序
合并两个有序单链表,合并后依然有序
判断两个单链表是否相交—链表不带环
求两个单链表相交的交点—链表不带环
测试

判断链表是否带环,返回相遇点
获取环的入口点
获取环的长度
判断两个链表是否相交,链表可能带环
测试

复杂链表的复制

逆序打印单链表
void PrintSListFromTail2Head(PNode pHead)       
{
    PNode pTail = NULL;
    PNode pCur = pHead;
    PNode pPre = NULL;
    if (NULL == pHead)
        return;
    while (pCur)
    {
        pTail = pCur;
        pCur = pCur->_pNext;
    }
    while (pTail!=pHead)
    {
        pCur = pHead;
        while (pCur!=pTail)
        {
            pPre = pCur;
            pCur = pCur->_pNext;

        }
        printf("%d->", pTail->_data);
        pTail = pPre;
    }
    printf("%d->NULL\n", pTail->_data);

//递归实现
#if 0
    if(pHead->_pNext)
    {
        PrintSListFromTail2Head(pHead->_pNext);
    }
    printf("->%d", pHead->_data);

#endif
}

删除链表的非尾结点,要求:不能遍历链表
void DeleteListNotTailNode(PNode pos)
{
    PNode pNext = NULL;
    pNext = pos->_pNext;
    pos->_data = pNext->_data;
    pos->_pNext = pNext->_pNext;
    free(pNext);
    pNext = NULL;
}

在链表pos位置前插入值到data的结点
/*在链表后边插入,然后将pos的值给后边的,再将值给pos*/
void InesrtPosFront(PNode pos, DataType data)
{
    PNode pNext = BuySListNode(data);
    pNext->_pNext = pos->_pNext;
    pos->_pNext = pNext;
    pNext->_data = pos->_data;
    pos->_data = data;
}

查找链表的中间结点,要求只能遍历一次链表
/*定义两个指针,一个一次走两步,一个走一步*/
PNode FindMiddleNode(PNode pHead)
{
    PNode pFast = pHead;
    PNode pSlow = pHead;
    if (NULL == pHead)
    {
        return NULL;
    }
    else if (NULL == pHead->_pNext)
    {
        return pHead;
    }
    else
    {
        while (pFast&&pFast->_pNext)
        {
            pFast = pFast->_pNext->_pNext;
            pSlow = pSlow->_pNext;
        }
        return  pSlow;
    }
}

查找链表的倒数第K个结点,要求只能遍历一次链表
PNode FindLastKNode(PNode pHead, int K)
{
    PNode pSlow = pHead;
    PNode pFast = pHead;
    if (NULL == pHead || K <= 0)
    {
        return NULL;
    }
    while (K--)
    {
        pFast = pFast->_pNext;
    }
    while (pFast)
    {
        pFast = pFast->_pNext;
        pSlow = pSlow->_pNext;
    }

    return pSlow;
}

// 删除链表的倒数第K个结点,要求只能遍历一次链表

void DeleteLastKNode(PNode pHead, int K)
{
    PNode pSlow = pHead;
    PNode pFast = pHead;
    PNode pPre = NULL;
    if (NULL == pHead || K <= 0)
    {
        return;
    }
    while (K--)
    {
        pFast = pFast->_pNext;
    }
    while (pFast)
    {
        pFast = pFast->_pNext;
        pPre = pSlow;
        pSlow = pSlow->_pNext;
    }
    pPre->_pNext = pSlow->_pNext;
    free(pSlow);
    pSlow = NULL;

}

用单链表实现约瑟夫环
void JosephCircle(PNode* pHead, const int M)
{
    PNode pCur = NULL;
    PNode pDel = NULL;
    int count = 0 ;
    assert(pHead);
    if (NULL == *pHead|| M <= 0)
    {
        return;
    }
    pCur = *pHead;
    //先遍历链表,让尾指向头
    while (pCur->_pNext)
    {
        pCur = pCur->_pNext;
    }
    pCur->_pNext = *pHead;
    pCur = *pHead;
    while ((pCur)->_pNext != pCur)
    {
        count = M;
        while (--count)                     //为什么时--M
        {
            pCur = pCur->_pNext;
        }
        //删节点
        pDel = pCur->_pNext;
        pCur->_data = pDel->_data;
        pCur->_pNext = pDel->_pNext;
        free(pDel);
        pDel = NULL;

    }
    //解环
    pCur->_pNext = NULL;

    SListPrint(pCur);
}

链表的逆置–三个指针

void ReverseSList(PNode* pHead)
{
    PNode pPre = NULL;
    PNode pCur = NULL;
    PNode pNext = NULL;
    assert(pHead);
    pCur = *pHead;
    while (pCur)
    {
        pNext = pCur->_pNext;
        pCur->_pNext = pPre;
        pPre = pCur;
        pCur = pNext;
    }
    *pHead = pPre;
}

链表的逆置–头插法

PNode ReverseSListOP(PNode pHead)
{
    PNode pCur = NULL;
    PNode pNewNode= NULL;
    if (NULL == pHead || NULL == pHead->_pNext)
        return NULL;

    while (pHead)
    {   
        pCur = pHead;
        pHead = pCur->_pNext;
        pCur->_pNext = pNewNode;
        pNewNode = pCur;
    }
    pHead = pCur;

    return pHead;
}

用冒泡排序思想对单链表进行排序

void BubbleSort(PNode pHead)
{
    PNode pTail = NULL;
    PNode pCur = pHead;
    int flag = 0;
    if (pHead == NULL || pHead->_pNext == NULL) 
    {
        return;
    }
    while (pTail != pHead)
    {
        pCur = pHead;
        flag = 0;
//这里为pCur->_pNext是为了防止if语句的中pCur->_pNext为空,如果为空第一次比较程序就会崩溃
        while (pCur->_pNext != pTail)           
        {
            if (pCur->_data < pCur->_pNext->_data)
            {
                DataType temp = pCur->_data;
                pCur->_data = pCur->_pNext->_data;
                pCur->_pNext->_data = temp;
                flag = 1;
            }

            pCur = pCur->_pNext;
        }
        pTail = pCur;
        if (0 == flag)
            break;
    }
}

合并两个有序单链表,合并后依然有序
PNode MergeSList(PNode pHead1, PNode pHead2)
{
    PNode pNewHead = NULL;
    PNode pCur = NULL;

    if (!pHead1)
        return pHead2;
    if (!pHead2)
        return pHead1;
    if (pHead1->_data >= pHead2->_data)
    {
        pCur = BuySListNode(pHead2->_data);
        pHead2 = pHead2->_pNext;
        pNewHead = pCur;
    }
    else if (pHead1->_data < pHead2->_data)
    {
        pCur = BuySListNode(pHead1->_data);
        pHead1 = pHead1->_pNext;
        pNewHead = pCur;
    }

    while (pHead1&&pHead2)
    {
        if (pHead1->_data >= pHead2->_data)
        {
            pCur->_pNext = BuySListNode(pHead2->_data);
            pHead2 = pHead2->_pNext;
            pCur = pCur->_pNext;
        }
        else if (pHead1->_data < pHead2->_data)
        {
            pCur->_pNext = BuySListNode(pHead1->_data);
            pHead1 = pHead1->_pNext;
            pCur = pCur->_pNext;
        }
    }
    while (pHead1)
    {
        pCur->_pNext = BuySListNode(pHead1->_data);
        pHead1 = pHead1->_pNext;
        pCur = pCur->_pNext;
    }
    while (pHead2)
    {
        pCur->_pNext = BuySListNode(pHead2->_data);
        pHead2= pHead2->_pNext;
        pCur = pCur->_pNext;
    }

    return pNewHead;
}

判断两个单链表是否相交—链表不带环
int IsSListCross(PNode pHead1, PNode pHead2)
{
    if (NULL == pHead1 || NULL == pHead2)
        return 0;
    //找到链表的最后一个节点
    while (pHead1->_pNext)
    {
        pHead1 = pHead1->_pNext;
    }
    while (pHead2->_pNext)
    {
        pHead2 = pHead2->_pNext;
    }
    if (pHead1 == pHead2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

求两个单链表相交的交点—链表不带环
/*先让长的链表遍历size1-size2,再让两个链表一起遍历,
            当pCur1==pCur2时,两链表相交*/
PNode GetCorssNode(PNode pHead1, PNode pHead2)
{
    if (NULL == pHead1 || NULL == pHead2)
        return NULL;
    int size1 = 0;
    int size2 = 0;
    int gap = 0;
    PNode pCur1 = pHead1;
    PNode pCur2 = pHead2;
    while (pCur1)
    {
        pCur1 = pCur1->_pNext;
        size1++;
    }
    while (pCur2)
    {
        pCur2 = pCur2->_pNext;
        size2++;
    }
    gap = size1 - size2;
    pCur1 = pHead1; pCur2 = pHead2;
    if (gap > 0)
    {
        while (gap--)
        {
            pCur1 = pCur1->_pNext;
        }
    }
    else
    {
        while (gap++)
        {
            pCur2 = pCur2->_pNext;
        }
    }
    while (pCur1 != pCur2)
    {
        pCur1 = pCur1->_pNext;
        pCur2 = pCur2->_pNext;
    }
    return pCur2;
}

测试程序
void TestInterview()
{
    PNode pHead1, pHead2,pCur;

    SListInit(&pHead1);
    SListPushBlack(&pHead1, 1);
    SListPushBlack(&pHead1, 5);
    SListPushBlack(&pHead1, 9);
    SListPushBlack(&pHead1, 3);
    SListPushBlack(&pHead1, 6);
    SListPushBlack(&pHead1, 34);
    SListPrint(pHead1);
    SListInit(&pHead2);
    SListPushBlack(&pHead2, 2);
    SListPushBlack(&pHead2, 4);

    pHead2->_pNext->_pNext = SListFind(pHead1,6);
    SListPrint(pHead2);
    pCur = GetCorssNode(pHead1, pHead2);
    //int ret = IsSListCross(pHead1, pHead2);


    //SListPushBlack(&pHead2, 6);
    //SListPushBlack(&pHead2, 34);
    //SListPrint(pHead2);


    //pCur = MergeSList(pHead1, pHead2);
    //SListPrint(pCur);

    //PrintSListFromTail2Head(pHead);
    //pCur = SListFind(pHead, 6);
    //DeleteListNotTailNode(pCur);
    //InesrtPosFront(pCur, 5);
    //SListPrint(pHead);

    /*pCur = FindMiddleNode(pHead);*/
    //pCur = FindLastKNode(pHead, 3);

    //DeleteLastKNode(pHead, 3);
    //SListPrint(pHead);

    //JosephCircle(&pHead, 3);

    //ReverseSList(&pHead);
    /*SListPrint(pHead);

    pHead = ReverseSListOP(pHead);
    SListPrint(pHead);*/

    /*BubbleSort(pHead);
    SListPrint(pHead);*/
}

判断两个链表是否相交,链表可能带环
PNode IsListWithCircle(PNode pHead1)
{
    PNode pFast = pHead1;
    PNode pSlow = pHead1;
    if (NULL == pHead1)
        return NULL;

    while (pFast && pFast->_pNext)
    {
        pFast = pFast->_pNext->_pNext;
        pSlow = pSlow->_pNext;

        if (pSlow == pFast)
            return pSlow;
    }

    return NULL;
}

获取环的入口点
PNode GetCircleEnter(PNode pHead1, PNode pMeetNode)
{
    PNode pH = pHead1;
    PNode pM = pMeetNode;
    if (NULL == pHead1 || NULL == pMeetNode)
    {
        return NULL;
    }
    else
    {
        while (pH != pM)
        {
            pH = pH->_pNext;
            pM = pM->_pNext;
        }
    }

    return pM;
}

获取环的长度
int GetCircleLen(PNode pMeetNode)
{
    PNode pCur = pMeetNode;
    int len = 1;
    if (NULL == pMeetNode)
    {
        return 0;
    }
    else
    {
        while (pCur->_pNext != pMeetNode)
        {
            pCur = pCur->_pNext;
            len++;
        }
    }

    return len;
}

判断两个链表是否相交,链表可能带环

int IsSListCrossWithCircle(PNode pHead1, PNode pHead2)
{
    PNode pSlow = NULL;
    PNode pFast = NULL;
    if (NULL == pHead1 || NULL == pHead2)
        return 0;

    pSlow = pHead1;
    pFast = pHead2;

    while (pFast&&pFast->_pNext)
    {
        pFast = pFast->_pNext->_pNext;
        pSlow = pSlow->_pNext;
        if (pFast == pSlow)
            return 1;
    }

    return 0;
}

测试
void TestInterview2()
{
    PNode pHead, pCur;

    SListInit(&pHead);
    SListPushBlack(&pHead, 1);
    SListPushBlack(&pHead, 3);
    SListPushBlack(&pHead, 6);
    SListPushBlack(&pHead, 9);
    SListPushBlack(&pHead, 7);
    SListPushBlack(&pHead, 4);
    SListPushBlack(&pHead, 8);
    SListPrint(pHead);

    pCur = pHead;
    while (NULL != pCur->_pNext)
        pCur = pCur->_pNext;
    pCur->_pNext = SListFind(pHead, 7);



    PNode pMeetNode = IsListWithCircle(pHead);
    PNode pEnterNode = GetCircleEnter(pHead, pMeetNode);
    int len = GetCircleLen(pMeetNode);

}

复杂链表的复制
PCSLNode CopyComplexList(PCSLNode pHead)
{
    PCSLNode pCur = pHead;
    PCSLNode pNewNode = NULL;
    PCSLNode pNewHead = NULL;
    if (NULL == pHead)
        return NULL;

    //1.在链表后面插入值相同的新节点
    while (pCur)
    {
        pNewNode = BuyCSNewNode(pCur->data);
        pNewNode->_pNext = pCur->_pNext;
        pCur->_pNext = pNewNode;
        pCur = pNewNode->_pNext;
    }
    pCur = pHead;

    //2.给新节点的随机指针域赋值
    //让随机指针域指向原节点随机指针指向的下个节点
    while (pCur)
    {
        pNewNode = pCur->_pNext;
        if (pCur->_pRandom)
        {
            pNewNode->_pRandom = pCur->_pRandom->_pNext;
        }
        pCur = pNewNode->_pNext;

    }

    //3.将新节点从原链表中拆下来
    pCur = pHead;
    pNewHead = pHead->_pNext;
    while (pCur->_pNext)
    {
        pNewNode = pCur->_pNext;
        pCur->_pNext = pNewNode->_pNext;
        pCur = pNewNode;

    }

    return pNewHead;
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页