利用链表快慢指针对链表进行查找

寻找中间节点

快指针每次移动两个位置,慢指针每次移动一个位置,当快指针到达末尾,慢指针所指的位置就是中间节点(在快指针一次循环中移动两个位置时,移动一个位置就需要判断该位置是否为末尾位置)

LinkNode *FindMidLinkNode(LinkNode *pHead)
{
    LinkNode *pFast = NULL;
    LinkNode *pSlow = NULL;

    pFast = pSlow = pHead->pNext;
    while (pFast != NULL)
    {
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            break;
        }
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            break;
        }

        pSlow = pSlow->pNext;
    }

    return pSlow;
}

查找倒数第K个位置

将快指针置于链表开始的第K个节点,随后将两个指针一起移动,当快指针到达末尾,慢指针所指向的位置就是目标位置

LinkNode *FindLastKthLinkNode(LinkNode *pHead, int k)
{
    LinkNode *pFast = pHead->pNext;
    LinkNode *pSlow = pHead->pNext;
    int i = 0;

    for (i = 0; i < k; i++)
    {
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            break;
        }
    }

    if (NULL == pFast)
    {
        return NULL;
    }

    while (pFast != NULL)
    {
        pSlow = pSlow->pNext;
        pFast = pFast->pNext;
    }

    return pSlow;
}

倒置链表

​
    int ReversalLinkList(LinkNode *pHead)
{
    LinkNode *pTmpNode = NULL;
    LinkNode *pInsertNode = NULL;

    pTmpNode = pHead->pNext;
    pHead->pNext = NULL;
    pInsertNode = pTmpNode;

    while (pTmpNode != NULL)
    {
        pTmpNode = pTmpNode->pNext;
        pInsertNode->pNext = pHead->pNext;
        pHead->pNext = pInsertNode;
        pInsertNode = pTmpNode;
    }

    return 0;
}

​

链表的冒泡排序

int BubbleSortLinkList(LinkNode *pHead)
{
    LinkNode *pTmpNode1 = NULL;
    LinkNode *pTmpNode2 = NULL;
    LinkNode *pend = NULL;
    DataType TmpData;

    //如果链表没有节点或者只有一个结点返回0
    if(NULL == pHead->pNext)
    {
        return 0;
    }
    while(1)
    {
        pTmpNode1 = pHead->pNext;
        pTmpNode2 = pHead->pNext->pNext;
        if(pTmpNode2 == pend)
        {
            break;
        }
        while(pTmpNode2 != pend)
        {
            if(pTmpNode1->Data > pTmpNode2->Data)
                        {
                            TmpData = pTmpNode1->Data;
                            pTmpNode1->Data = pTmpNode2->Data;
                            pTmpNode2->Data = TmpData;

                        }
                pTmpNode1 = pTmpNode1->pNext;
                pTmpNode2 = pTmpNode2->pNext;
        
        }
             pend = pTmpNode1;
    }
    return 0;
}

链表的选择排序

定义三个指针,分别为最小指针,遍历指针,以及标志位指针,即指向链表末尾指针(根据排序需求设置)

int SelectSortLinkList(LinkNode *pHead)
{
    LinkNode *pTmpNode = NULL;
    LinkNode *pMinNode = NULL;
    LinkNode *pSwapNode = NULL;
    DataType TmpData;

    if (NULL == pHead->pNext)
    {
        return 0;
    }

    pSwapNode = pHead->pNext;

    while (pSwapNode->pNext != NULL)
    {
        pMinNode = pSwapNode;
        pTmpNode = pSwapNode->pNext;
        while (pTmpNode != NULL)
        {
            if (pTmpNode->Data < pMinNode->Data)
            {
                pMinNode = pTmpNode;
            }
            pTmpNode = pTmpNode->pNext;
        }
        if (pMinNode != pSwapNode)
        {
            TmpData = pMinNode->Data;
            pMinNode->Data = pSwapNode->Data;
            pSwapNode->Data = TmpData;
        }
        pSwapNode = pSwapNode->pNext;
    } 

    return 0;
}

关于链表的几个问题

1.已知链表中间某个节点地址,不知道头结点地址,如何删除该节点
将该节点后面的节点值依次向前覆盖前一个节点的数值。

2.如何判断一个链表是否有环?环长?

使用快慢指针的方法,如果两个指针能够相遇,就证明该链表为有环链表。设置计数器得到环长。

LinkNode *IsHasCircle(LinkNode *pHead, int *pcnt)
{
    LinkNode *pFast = NULL;
    LinkNode *pSlow = NULL;
    LinkNode *pTmpNode = NULL;
    LinkNode *pNode1 = NULL;
    LinkNode *pNode2 = NULL;
    int ret = 0;
    int cnt = 1;

    pSlow = pFast = pHead->pNext;
    while (1)
    {
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            ret = 0;
            break;
        }
        pFast = pFast->pNext;
        if (NULL == pFast)
        {
            ret = 0;
            break;
        }

        pSlow = pSlow->pNext;
        if (pSlow == pFast)
        {
            ret = 1;
            break;
        }
    }

    if (1 == ret)
    {
        //获得环长
        pTmpNode = pSlow->pNext;
        while (pTmpNode != pSlow)
        {
            cnt++;
            pTmpNode = pTmpNode->pNext;
        }
        *pcnt = cnt;

        //获得环入口位置
        pNode1 = pSlow;
        pNode2 = pHead->pNext;
        while (1)
        {
            pNode1 = pNode1->pNext;
            pNode2 = pNode2->pNext;
            if (pNode1 == pNode2)
            {
                return pNode1;
            }
        }
    }

    return NULL;
}
 while (pLastNode->pNext != NULL)
    {
        pLastNode = pLastNode->pNext;
    }
    pLastNode->pNext = phead->pNext->pNext->pNext->pNext->pNext->pNext->pNext->pNext->pNext->pNext;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值