1. 程式人生 > >劍指Offer面試題:25.二叉搜尋樹與雙向連結串列

劍指Offer面試題:25.二叉搜尋樹與雙向連結串列

一、題目:二叉搜尋樹與雙向連結串列

題目:輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。比如輸入下圖中左邊的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列。

  二叉搜尋樹的節點定義如下,這裡使用C#語言描述:

    public class BinaryTreeNode
    {
        public int Data { get; set; }
        public BinaryTreeNode leftChild { get; set; }
        public
BinaryTreeNode rightChild { get; set; } public BinaryTreeNode(int data) { this.Data = data; } public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right) { this.Data = data; this.leftChild = left;
this.rightChild = right; } }

二、解題思路

2.1 核心步驟

  首先,我們知道:在二叉樹中,每個結點都有兩個指向子結點的指標。在雙向連結串列中,每個結點也有兩個指標,它們分別指向前一個結點和後一個結點。

  其次,由於要求轉換之後的連結串列是排好序的,我們可以中序遍歷樹中的每一個結點,這是因為中序遍歷演算法的特點是按照從小到大的順序遍歷二叉樹的每一個結點。

  最後,按照中序遍歷的順序,當我們遍歷轉換到根結點(值為10的結點)時,它的左子樹已經轉換成一個排序的連結串列了,並且處在連結串列中的最後一個結點是當前值最大的結點。我們把值為8的結點和根結點連結起來,此時連結串列中的最後一個結點就是10了。接著我們去遍歷轉換右子樹,並把根結點和右子樹中最小的結點連結起來。

  很明顯,轉換它的左子樹和右子樹,由於遍歷和轉換過程是一樣的,很自然地想到可以用遞迴

2.2 程式碼實現

    public BinaryTreeNode Convert(BinaryTreeNode root)
    {
        BinaryTreeNode lastNodeInList = null;
        ConvertNode(root, ref lastNodeInList);

        // lastNodeInList指向雙向連結串列的尾結點,
        // 我們需要返回頭結點
        BinaryTreeNode headInList = lastNodeInList;
        while (headInList != null && headInList.leftChild != null)
        {
            headInList = headInList.leftChild;
        }

        return headInList;
    }

    private void ConvertNode(BinaryTreeNode node, ref BinaryTreeNode lastNodeInList)
    {
        if (node == null)
        {
            return;
        }

        BinaryTreeNode currentNode = node;
        // 轉換左子樹
        if (currentNode.leftChild != null)
        {
            ConvertNode(currentNode.leftChild, ref lastNodeInList);
        }
        // 與根節點的銜接
        currentNode.leftChild = lastNodeInList;
        if (lastNodeInList != null)
        {
            lastNodeInList.rightChild = currentNode;
        }
        lastNodeInList = currentNode;
        // 轉換右子樹
        if (currentNode.rightChild != null)
        {
            ConvertNode(currentNode.rightChild, ref lastNodeInList);
        }
    }

三、單元測試

3.1 測試用例

  (1)輔助方法的封裝

    private void SetSubTreeNode(BinaryTreeNode root, BinaryTreeNode lChild, BinaryTreeNode rChild)
    {
        if (root == null)
        {
            return;
        }

        root.leftChild = lChild;
        root.rightChild = rChild;
    }

    private BSTConverter converter;

    [TestInitialize]
    public void Initialize()
    {
        converter = new BSTConverter();
    }

    [TestCleanup]
    public void CleanUp()
    {
        converter = null;
    }
View Code

  (2)功能測試、特殊輸入測試

    //            10
    //         /      \
    //        6        14
    //       /\        /\
    //      4  8     12  16
    [TestMethod]
    public void ConvertTest1()
    {
        BinaryTreeNode node10 = new BinaryTreeNode(10);
        BinaryTreeNode node6 = new BinaryTreeNode(6);
        BinaryTreeNode node4 = new BinaryTreeNode(4);
        BinaryTreeNode node8 = new BinaryTreeNode(8);
        BinaryTreeNode node14 = new BinaryTreeNode(14);
        BinaryTreeNode node12 = new BinaryTreeNode(12);
        BinaryTreeNode node16 = new BinaryTreeNode(16);

        SetSubTreeNode(node10, node6, node14);
        SetSubTreeNode(node6, node4, node8);
        SetSubTreeNode(node14, node12, node16);

        BinaryTreeNode result = converter.Convert(node10);
        Assert.AreEqual(result, node4);
    }

    //               5
    //              /
    //             4
    //            /
    //           3
    //          /
    //         2
    //        /
    //       1
    [TestMethod]
    public void ConvertTest2()
    {
        BinaryTreeNode node5 = new BinaryTreeNode(5);
        BinaryTreeNode node4 = new BinaryTreeNode(4);
        BinaryTreeNode node3 = new BinaryTreeNode(3);
        BinaryTreeNode node2 = new BinaryTreeNode(2);
        BinaryTreeNode node1 = new BinaryTreeNode(1);

        node5.leftChild = node4;
        node4.leftChild = node3;
        node3.leftChild = node2;
        node2.leftChild = node1;

        BinaryTreeNode result = converter.Convert(node5);
        Assert.AreEqual(result, node1);
    }

    // 1
    //  \
    //   2
    //    \
    //     3
    //      \
    //       4
    //        \
    //         5
    [TestMethod]
    public void ConvertTest3()
    {
        BinaryTreeNode node5 = new BinaryTreeNode(5);
        BinaryTreeNode node4 = new BinaryTreeNode(4);
        BinaryTreeNode node3 = new BinaryTreeNode(3);
        BinaryTreeNode node2 = new BinaryTreeNode(2);
        BinaryTreeNode node1 = new BinaryTreeNode(1);

        node1.rightChild = node2;
        node2.rightChild = node3;
        node3.rightChild = node4;
        node4.rightChild = node5;

        BinaryTreeNode result = converter.Convert(node1);
        Assert.AreEqual(result, node1);
    }

    // 樹中只有1個結點
    [TestMethod]
    public void ConvertTest4()
    {
        BinaryTreeNode node1 = new BinaryTreeNode(1);

        BinaryTreeNode result = converter.Convert(node1);
        Assert.AreEqual(result, node1);
    }

    // 空指標
    [TestMethod]
    public void ConvertTest5()
    {
        BinaryTreeNode result = converter.Convert(null);
        Assert.AreEqual(result, null);
    } 

3.2 測試結果

  (1)測試通過情況

  (2)程式碼覆蓋率

作者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

Offer試題25.搜尋雙向連結串列

一、題目:二叉搜尋樹與雙向連結串列 題目:輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。比如輸入下圖中左邊的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列。   二叉搜尋樹的節點定義如下,這裡使用C#語言描述:

offer刷題記錄26——搜尋雙向連結串列

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 public class Solution { public TreeNode Convert(TreeNode root) {

Offer試題22.搜尋的後序遍歷序列

一、題目:二叉搜尋樹的後序遍歷序列 題目:輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則返回true,否則返回false。假設輸入的陣列的任意兩個數字都互不相同。   例如在下面的一顆二叉搜尋樹中,輸入陣列{5,7,6,9,11,10,8},則返回true,因為這個整數序列是

offer 試題重建

題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。 思路:二叉樹先序是根左右,中序 是左根右。所以先找到

Offer學習】【試題27搜尋雙向連結串列

題目:輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 比如輸入圖4.12 中左邊的二叉搜尋樹,則輸出轉換之後的排序現向連結串列。 結點定義: public static

offer試題36搜尋雙向連結串列

題目:輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。  比如如下圖中的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列為:  在二叉樹中,每個結點都有兩個指向子節點的指標。在雙向連結串

Offer試題23.中和為某一值的路徑

一、題目:二叉樹中和為某一值的路徑 題目:輸入一棵二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。例如輸入下圖中二叉樹和整數22,則打印出兩條路徑,第一條路徑包含結點10、12,第二條路徑包含結點10、5和7。   二叉

offer試題的映象(遞迴、迴圈解法及測試用例)

題目:給定二叉樹,將其變換為源二叉樹的映象。 二叉樹的定義如下: struct TreeNode {     int val;     TreeNode* left;     TreeNode* right; }; 輸入描述: 二叉樹的映象定義:     源二叉樹    

offer--試題27:搜尋雙向連結串列--Java實現

題目描述: 輸入一顆二叉搜尋樹,將二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 思路: 原先指向左子結點的指標調整為連結串列中指向前一個結點的指標,原先指向右子結點的指標指向為連結串列中指向後一個結點的指標

offer第二版面試題36搜尋雙向連結串列(java)

題目描述: 輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立新的結點,只能調整樹中結點指標的指向。 比如如下圖中的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列為: 分析: 在二叉樹中,每個結點都有兩個指向子節點的指標。在雙

Offer - 26搜尋雙向連結串列

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向 題目連結:https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5

offer程式設計題(JAVA實現)——第26題搜尋雙向連結串列

github https://github.com/JasonZhangCauc/JZOffer /** * * 劍指offer程式設計題(JAVA實現)——第26題:二叉搜尋樹與雙向連結串列

offer搜尋雙向連結串列(Python)

站在巨人的肩膀上,風景這邊獨好; 親自爬上巨人的肩膀,才知風景為什麼這麼美。 題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。如圖: 解題思路 吐

關於offer上“搜尋雙向連結串列”題的理解

題目描述: 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 一、遞迴的思路 對於函式TreeNode* Convert(TreeNode* root),傳入的是需要轉換的二叉樹的頭結點,返回的是已經轉換好的

offer -- 搜尋雙向連結串列

題目 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 AC程式碼 /** public class TreeNode { int val = 0; TreeNode left = null;

offer系列(十一)搜尋雙向連結串列, 字串的排序

二叉搜尋樹與雙向連結串列 題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 解題思路: 由於輸入的一個二叉搜尋樹,其左子樹小於右子樹的值,這位後面的排序做了準備,因為只需要中序遍歷即可,將所有 的節點儲存

Offer 26. 搜尋雙向連結串列搜尋

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 題目地址 https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=1

[offer] --26.搜尋雙向連結串列

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 /** public class TreeNode { int val = 0; TreeNode left = null; Tr

offer》系列 搜尋雙向連結串列(Java)

連結 牛客: 二叉搜尋樹與雙向連結串列 題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 思路 這個程式碼是借鑑網上的,整體結構和中序遍歷非常類似,只不過將原本輸出那部分的操作換成了改變結

Offer - 搜尋雙向連結串列(Java實現)

題目描述: 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 思路分析: 二叉搜尋樹(BST)有一個很關鍵的結論就是:中序遍歷的結果是非遞減(遞增)序列。而本題要求將BST轉換成排序的雙向連結串列,核