劍指Offer面試題:16.合並兩個排序的鏈表


PS:這也是一道出鏡率極高的面試題,我相信很多童鞋都會很眼熟,就像於千萬人之中遇見不期而遇的人,沒有別的話可說,唯有輕輕地問一聲:“哦,原來你也在這里? ”

一、題目:合並兩個排序的鏈表

題目:輸入兩個遞增排序的鏈表,合並這兩個鏈表並使新鏈表中的結點仍然是按照遞增排序的。例如輸入下圖中的鏈表1和鏈表2,則合並之后的升序鏈表如鏈表3所示。

  鏈表結點定義如下,使用C#描述:

    public class Node
    {
        public int Data { get; set; }
        // 指向后一個節點
        public Node Next { get; set; }

        public Node(int data)
        {
            this.Data = data;
        }

        public Node(int data, Node next)
        {
            this.Data = data;
            this.Next = next;
        }
    }

二、解題思路

  Step1.定義一個指向新鏈表的指針,暫且讓它指向NULL;

  Step2.比較兩個鏈表的頭結點,讓較小的頭結點作為新鏈表的頭結點;

  Step3.遞歸比較兩個鏈表的其余節點,讓較小的節點作為上一個新節點的后一個節點;

    public Node Merge(Node head1, Node head2)
    {
        if (head1 == null)
        {
            return head2;
        }
        else if (head2 == null)
        {
            return head1;
        }

        Node newHead = null;

        if (head1.Data <= head2.Data)
        {
            newHead = head1;
            newHead.Next = Merge(head1.Next, head2);
        }
        else
        {
            newHead = head2;
            newHead.Next = Merge(head1, head2.Next);
        }

        return newHead;
    }

三、單元測試

3.1 測試准備

  (1)借助MSUnit框架進行初始化與清理工作[TestInitialize]與[TestCleanup]

    private MergeHelper mergeHelper;

    [TestInitialize]
    public void Initialize()
    {
        // 實例化
        mergeHelper = new MergeHelper();
    }

    [TestCleanup]
    public void CleanUp()
    {
        // 不用TA了
        mergeHelper = null;
    } 

  (2)封裝一個便於測試對比的輔助方法,將新鏈表生成一個字符串用於對比

    public string GetListString(Node head)
    {
        if (head == null)
        {
            return null;
        }

        StringBuilder sbList = new StringBuilder();
        while (head != null)
        {
            sbList.Append(head.Data.ToString());
            head = head.Next;
        }

        return sbList.ToString();
    } 

3.2 測試用例

  (1)功能測試

    // list1: 1->3->5
    // list2: 2->4->6
    [TestMethod]
    public void MergeTest1()
    {
        Node node1 = new Node(1);
        Node node3 = new Node(3);
        Node node5 = new Node(5);

        node1.Next = node3;
        node3.Next = node5;

        Node node2 = new Node(2);
        Node node4 = new Node(4);
        Node node6 = new Node(6);

        node2.Next = node4;
        node4.Next = node6;

        Node newHead = mergeHelper.Merge(node1, node2);
        Assert.AreEqual(GetListString(newHead), "123456");
    }

    // 兩個鏈表中有重復的數字
    // list1: 1->3->5
    // list2: 1->3->5
    [TestMethod]
    public void MergeTest2()
    {
        Node node1 = new Node(1);
        Node node3 = new Node(3);
        Node node5 = new Node(5);

        node1.Next = node3;
        node3.Next = node5;

        Node node2 = new Node(1);
        Node node4 = new Node(3);
        Node node6 = new Node(5);

        node2.Next = node4;
        node4.Next = node6;

        Node newHead = mergeHelper.Merge(node1, node2);
        Assert.AreEqual(GetListString(newHead), "113355");
    } 

  (2)特殊輸入測試

    // 兩個鏈表都只有一個數字
    // list1: 1
    // list2: 2
    [TestMethod]
    public void MergeTest3()
    {
        Node node1 = new Node(1);
        Node node2 = new Node(2);

        Node newHead = mergeHelper.Merge(node1, node2);
        Assert.AreEqual(GetListString(newHead), "12");
    }

    // 兩個鏈表中有一個空鏈表
    // list1: 1->3->5
    // list2: null
    [TestMethod]
    public void MergeTest4()
    {
        Node node1 = new Node(1);
        Node node3 = new Node(3);
        Node node5 = new Node(5);

        node1.Next = node3;
        node3.Next = node5;

        Node newHead = mergeHelper.Merge(node1, null);
        Assert.AreEqual(GetListString(newHead), "135");
    }

    // 兩個鏈表都是空鏈表
    // list1: null
    // list2: null
    [TestMethod]
    public void MergeTest5()
    {
        Node newHead = mergeHelper.Merge(null, null);
        Assert.AreEqual(GetListString(newHead), null);
    } 

3.3 測試結果

  (1)測試通過情況

  (2)代碼覆蓋率

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM