1. 程式人生 > >連結串列面試題之合併兩個有序連結串列

連結串列面試題之合併兩個有序連結串列

關於合併兩個有序的連結串列,假定該連結串列為升序排列,排列後的新表依舊升序。以下提供兩種方法進行排列。

  • 建立新節點為空,依次後續插入法
    Node* MergeTwoList1(Node* pHead1, Node* pHead2)
    { 
        // 先處理任意一個連結串列為空的情況
        if (pHead1 == NULL)
            return pHead2;
        if (pHead2 == NULL)
            return pHead1;
        // 定義新連結串列的頭結點
        Node*
NewNode = NULL; Node* p1 = pHead1; Node* p2 = pHead2; if (p1->_data > p2->_data) { NewNode = p2; p2 = p2->_next; } else { NewNode = p1; p1 = p1->_next; } // 標記新連結串列的尾節點
Node* ptail = NewNode; while (p1 && p2) { if (p1->_data > p2->_data) { ptail->_next = p2; ptail = ptail->_next; p2 = p2->_next; } else { ptail->
_next = p1; ptail = ptail->_next; p1 = p1->_next; } } // 跳出迴圈則p1為空或p2為空,若p2為空,則ptail的_next鏈向p1,否則鏈向p2 if (p1) ptail->_next = p1; else ptail->_next = p2; return NewNode; }
  • 以兩個連結串列的頭結點的值較小者為合併後的頭結點,依次後續插入法
    Node* MergeTwoList2(Node* pHead1, Node* pHead2)
    {
        if (pHead1 == NULL)
            return pHead2;
        if (pHead2 == NULL)
            return pHead1;
        Node* p1 = pHead1;
        Node* p2 = pHead2;
        // 找兩連結串列頭結點中值較小者,用p1指向,p2指向另一連結串列
        if (pHead1->_data < pHead2->_data)
            p1 = pHead1, p2 = pHead2;
        else
            p1 = pHead2, p2 = pHead1;
        // 標記新連結串列的頭結點
        Node* NewNode = p1;
        // 標記p1的前一個結點,以便後續插入新節點
        Node* prev = NewNode;
        p1 = p1->_next;
        while (p1 && p2)
        {
            // 若p1值大於p2,將p2結點插入到p1之前,否則直接更新prev和p1
            if (p1->_data > p2->_data)
            {
                // 標記p2的下一個結點,防止p2修改指向後找不到原表
                Node* p2Next = p2->_next;
                p2->_next = p1;
                prev->_next = p2;
                prev = p2;
                p2 = p2Next;
            }
            else
            {
                prev = p1;
                p1 = p1->_next;
            }
        }
        return NewNode;
    }