• 单链表核心代码


    暂时忽略特例情况

    1 单链表逆置

     // 利用两个指针变量存储当前节点和下一个节点的值

     link h=null;//第一个节点指针域置null 

     while(p) //p是头指针

    {

       link tmp=p;//指向一个节点

       p=p->next;//把p指向第二个节点

       //给第一个节点指针域附值

       p->next=h;

       h=tmp;//存储下一个将要存储的地址 

    }

      p=h;//赋给头指针

    2 判断链表循环链接

    //利用一快一慢,如果是环,则会相遇

    while (fast && fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;

            if (fast == slow)
            {
                return 1;
            }
        }

    3 寻找链表中的中间元素

    // 通过一个1步长,一个2步长,进行定位

    while (1)
        {
            if (NULL == fast->next || NULL == fast->next->next)
            {
                return slow;
            }

            slow = slow->next;
            fast = fast->next->next;

            /* Prevent that there is a loop in the linked list. */
            if (fast == slow)
            {
                return NULL;
            }
        }

    4 删除链表倒数第m个元素

    //两种思路:1.先计算链表长度,然后n-m,遍历二次链表

               2.设置头尾两个指针,间隔m个元素,同步向前移动,当尾指针到末尾时,头指针即为所需元素  

      list ahead = sll;
        list after = sll;

        if (NULL == ahead || m <= 0)
        {
            return NULL;
        }

        while (m--)
        {
            if (NULL == ahead)
            {
                return NULL;
            }
            ahead = ahead->next;

            if (fast && fast->next)
            {
                fast = fast->next->next;
                if (fast == ahead)
                {
                    return NULL;
                }
            }
        }

        while (1)
        {
            if (NULL == ahead)
            {
                return after;
            }
            ahead = ahead->next;
            after = after->next;

            if (fast && fast->next)
            {
                fast = fast->next->next;
                if (fast == ahead)
                {
                    return NULL;
                }
            }
        }

    5 判断一个链表部分是否是循环列表,如果是,找出其中开始相交的节点

    //两种方法:1.增加一个额外数组,保留所有经过的指针,每经过一个,比较是否出现过,时间复杂度O(n),空间复杂度O(n)

               2.利用两个指针,一个步长1,一个步长2,当第一次相遇的时候,另一个指针指向链表头,另一个继续,步长都为1,当相遇时刻则为交点节点处。

    给出2的代码实现:

        list slow = sll;
        list fast = sll;

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

        while (1)
        {
            if (NULL == fast->next || NULL == fast->next->next)
            {
                return NULL;
            }

            slow = slow->next;
            fast = fast->next->next;

            if (fast == slow)
            {
                slow = sll;
                break;
            }
        }

        while (1)
        {
            slow = slow->next;
            fast = fast->next;

            if (fast == slow)
            {
                return fast;
            }
        }

    6 给定链表的头指针和一个结点指针,在O(1) 时间删除该结点

    // 分情况,当节点是最后一个节点时,遍历删除;

       如果是中间节点,找到该节点的下一个,用下一个节点覆盖要删的节点

    void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted)

    {

          if(!pListHead || !pToBeDeleted)

                return;

     

          // if pToBeDeleted is not the last node in the list

          if(pToBeDeleted->m_pNext != NULL)

          {

                // copy data from the node next to pToBeDeleted

                ListNode* pNext = pToBeDeleted->m_pNext;

                pToBeDeleted->m_nKey = pNext->m_nKey;

                pToBeDeleted->m_pNext = pNext->m_pNext;

     

                // delete the node next to the pToBeDeleted

                delete pNext;

                pNext = NULL;

          }

          // if pToBeDeleted is the last node in the list

          else

          {

                // get the node prior to pToBeDeleted

                ListNode* pNode = pListHead;

                while(pNode->m_pNext != pToBeDeleted)

                {

                      pNode = pNode->m_pNext;            

                }

     

                // deleted pToBeDeleted

                pNode->m_pNext = NULL;

                delete pToBeDeleted;

                pToBeDeleted = NULL;

          }

    } 

    7 两个单向链表,找出它们的第一个公共结点

    //两种方式:1.遍历A列表,对每个A元素,与B中元素依次比较,如果相同则为,则为相交节点,时间复杂度O(m*n)

                     2.先得到两个列表A,B的长度,如果len(A)- len(B)=k,先A列表遍历K个元素,然后,A,B列表同步前进,当相遇的时刻,即为相交节点处。

                        时间复杂度:O(2(M+N))等于O(M+N)

    ///////////////////////////////////////////////////////////////////////

    // Find the first common node in the list with head pHead1 and

    // the list with head pHead2

    // Input: pHead1 - the head of the first list

    //        pHead2 - the head of the second list

    // Return: the first common node in two list. If there is no common

    //         nodes, return NULL

    ///////////////////////////////////////////////////////////////////////

    ListNode * FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2)

    {

          // Get the length of two lists

          unsigned int nLength1 = ListLength(pHead1);

          unsigned int nLength2 = ListLength(pHead2);

          int nLengthDif = nLength1 - nLength2;

     

          // Get the longer list

          ListNode *pListHeadLong = pHead1;

          ListNode *pListHeadShort = pHead2;

          if(nLength2 > nLength1)

          {

                pListHeadLong = pHead2;

                pListHeadShort = pHead1;

                nLengthDif = nLength2 - nLength1;

          }

     

          // Move on the longer list

          for(int i = 0; i < nLengthDif; ++ i)

                pListHeadLong = pListHeadLong->m_pNext;

     

          // Move on both lists

          while((pListHeadLong != NULL) &&

                (pListHeadShort != NULL) &&

                (pListHeadLong != pListHeadShort))

          {

                pListHeadLong = pListHeadLong->m_pNext;

                pListHeadShort = pListHeadShort->m_pNext;

          }

     

          // Get the first common node in two lists

          ListNode *pFisrtCommonNode = NULL;

          if(pListHeadLong == pListHeadShort)

                pFisrtCommonNode = pListHeadLong;

     

          return pFisrtCommonNode;

    }

     

    ///////////////////////////////////////////////////////////////////////

    // Get the length of list with head pHead

    // Input: pHead - the head of list

    // Return: the length of list

    ///////////////////////////////////////////////////////////////////////

    unsigned int ListLength(ListNode* pHead)

    {

          unsigned int nLength = 0;

          ListNode* pNode = pHead;

          while(pNode != NULL)

          {

                ++ nLength;

                pNode = pNode->m_pNext;

          }

     

          return nLength;

    }

  • 相关阅读:
    Json教程
    推荐一款华为最新的自动化代码检查工具
    如何选择版本控制系统
    从华为产品学到什么是devops
    DevCloud让代码检查更科学
    SVN如何迁移到Git?
    如何选择版本控制系统之二
    如何使用华为软件开发云快速部署PHP网站
    浅谈软件开发项目如何实现精益生产
    减负!云端编译构建,这样让你的开发省时省力……
  • 原文地址:https://www.cnblogs.com/wwwfj/p/3215132.html
Copyright © 2020-2023  润新知