1. 程式人生 > >二叉樹筆試題彙總

二叉樹筆試題彙總

樹是一種比較重要的資料結構,尤其是二叉樹。二叉樹是一種特殊的樹,在二叉樹中每個節點最多有兩個子節點,一般稱為左子節點和右子節點(或左孩子和右孩子),並且二叉樹的子樹有左右之分,其次序不能任意顛倒。二叉樹是遞迴定義的,因此,與二叉樹有關的題目基本都可以用遞迴思想解決,當然有些題目非遞迴解法也應該掌握,如非遞迴遍歷節點等等。本文努力對二叉樹相關題目做一個較全的整理總結,希望對找工作的同學有所幫助。

二叉樹節點定義如下:
struct BinaryTreeNode
{
    int m_nValue;
    BinaryTreeNode* m_pLeft;
    BinaryTreeNode* m_pRight;
};

1、求二叉樹中的節點個數

遞迴解法:

(1)如果二叉樹為空,節點個數為0
(2)如果二叉樹不為空,二叉樹節點個數 = 左子樹節點個數 + 右子樹節點個數 + 1
參考程式碼如下:
  1. int GetNodeNum(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL) // 遞迴出口
  4.         return 0;  
  5.     return GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1;  
  6. }  

2、求二叉樹的深度

遞迴解法:

(1)如果二叉樹為空,二叉樹的深度為0
(2)如果二叉樹不為空,二叉樹的深度 = max(左子樹深度, 右子樹深度) + 1

參考程式碼如下:
  1. int GetDepth(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL) // 遞迴出口
  4.         return 0;  
  5.     int depthLeft = GetDepth(pRoot->m_pLeft);  
  6.     int depthRight = GetDepth(pRoot->m_pRight);  
  7.     return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1); 
  8. }  

3、前序遍歷、中序遍歷、後序遍歷

前序遍歷遞迴解法:

(1)如果二叉樹為空,空操作

(2)如果二叉樹不為空,訪問根節點,前序遍歷左子樹,前序遍歷右子樹
參考程式碼如下:
  1. void PreOrderTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     Visit(pRoot); // 訪問根節點
  6.     PreOrderTraverse(pRoot->m_pLeft); // 前序遍歷左子樹
  7.     PreOrderTraverse(pRoot->m_pRight); // 前序遍歷右子樹
  8. }  
中序遍歷遞迴解法
(1)如果二叉樹為空,空操作。
(2)如果二叉樹不為空,中序遍歷左子樹,訪問根節點,中序遍歷右子樹
參考程式碼如下:
  1. void InOrderTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     InOrderTraverse(pRoot->m_pLeft); // 中序遍歷左子樹
  6.     Visit(pRoot); // 訪問根節點
  7.     InOrderTraverse(pRoot->m_pRight); // 中序遍歷右子樹
  8. }  
後序遍歷遞迴解法
(1)如果二叉樹為空,空操作
(2)如果二叉樹不為空,後序遍歷左子樹,後序遍歷右子樹,訪問根節點
參考程式碼如下:
  1. void PostOrderTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     PostOrderTraverse(pRoot->m_pLeft); // 後序遍歷左子樹
  6.     PostOrderTraverse(pRoot->m_pRight); // 後序遍歷右子樹
  7.     Visit(pRoot); // 訪問根節點
  8. }  

4、分層遍歷二叉樹(按層次從上往下,從左往右)

相當於廣度優先搜尋,使用佇列實現。佇列初始化,將根節點壓入佇列。當佇列不為空,進行如下操作:彈出一個節點,訪問,若左子節點或右子節點不為空,將其壓入佇列。

  1. void LevelTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     queue<BinaryTreeNode *> q;  
  6.     q.push(pRoot);  
  7.     while(!q.empty())  
  8.     {  
  9.         BinaryTreeNode * pNode = q.front();  
  10.         q.pop();  
  11.         Visit(pNode); // 訪問節點
  12.         if(pNode->m_pLeft != NULL)  
  13.             q.push(pNode->m_pLeft);  
  14.         if(pNode->m_pRight != NULL)  
  15.             q.push(pNode->m_pRight);  
  16.     }  
  17.     return;  
  18. }  

5、將二叉查詢樹變為有序的雙向連結串列

要求不能建立新節點,只調整指標。
遞迴解法:
(1)如果二叉樹查詢樹為空,不需要轉換,對應雙向連結串列的第一個節點是NULL,最後一個節點是NULL
(2)如果二叉查詢樹不為空:
如果左子樹為空,對應雙向有序連結串列的第一個節點是根節點,左邊不需要其他操作;
如果左子樹不為空,轉換左子樹,二叉查詢樹對應雙向有序連結串列的第一個節點就是左子樹轉換後雙向有序連結串列的第一個節點,同時將根節點和左子樹轉換後的雙向有序鏈 表的最後一個節點連線;
如果右子樹為空,對應雙向有序連結串列的最後一個節點是根節點,右邊不需要其他操作;
如果右子樹不為空,對應雙向有序連結串列的最後一個節點就是右子樹轉換後雙向有序連結串列的最後一個節點,同時將根節點和右子樹轉換後的雙向有序連結串列的第一個節點連 接。
參考程式碼如下:
  1. /****************************************************************************** 
  2. 引數: 
  3. pRoot: 二叉查詢樹根節點指標 
  4. pFirstNode: 轉換後雙向有序連結串列的第一個節點指標 
  5. pLastNode: 轉換後雙向有序連結串列的最後一個節點指標 
  6. ******************************************************************************/
  7. void Convert(BinaryTreeNode * pRoot,   
  8.              BinaryTreeNode * & pFirstNode, BinaryTreeNode * & pLastNode)  
  9. {  
  10.     BinaryTreeNode *pFirstLeft, *pLastLeft, * pFirstRight, *pLastRight;  
  11.     if(pRoot == NULL)   
  12.     {  
  13.         pFirstNode = NULL;  
  14.         pLastNode = NULL;  
  15.         return;  
  16.     }  
  17.     if(pRoot->m_pLeft == NULL)  
  18.     {  
  19.         // 如果左子樹為空,對應雙向有序連結串列的第一個節點是根節點
  20.         pFirstNode = pRoot;  
  21.     }  
  22.     else
  23.     {  
  24.         Convert(pRoot->m_pLeft, pFirstLeft, pLastLeft);  
  25.         // 二叉查詢樹對應雙向有序連結串列的第一個節點就是左子樹轉換後雙向有序連結串列的第一個節點
  26.         pFirstNode = pFirstLeft;  
  27.         // 將根節點和左子樹轉換後的雙向有序連結串列的最後一個節點連線
  28.         pRoot->m_pLeft = pLastLeft;  
  29.         pLastLeft->m_pRight = pRoot;  
  30.     }  
  31.     if(pRoot->m_pRight == NULL)  
  32.     {  
  33.         // 對應雙向有序連結串列的最後一個節點是根節點
  34.         pLastNode = pRoot;  
  35.     }  
  36.     else
  37.     {  
  38.         Convert(pRoot->m_pRight, pFirstRight, pLastRight);  
  39.         // 對應雙向有序連結串列的最後一個節點就是右子樹轉換後雙向有序連結串列的最後一個節點
  40.         pLastNode = pLastRight;  
  41.         // 將根節點和右子樹轉換後的雙向有序連結串列的第一個節點連線
  42.         pRoot->m_pRight = pFirstRight;  
  43.         pFirstRight->m_pLeft = pRoot;  
  44.     }  
  45.     return;  
  46. }  

6、求二叉樹第k層的節點個數

遞迴解法:

(1)如果二叉樹為空或者k<1返回0
(2)如果二叉樹不為空並且k==1,返回1
(3)如果二叉樹不為空且k>1,返回左子樹中k-1層的節點個數與右子樹k-1層節點個數之和
參考程式碼如下:
  1. int GetNodeNumKthLevel(BinaryTreeNode * pRoot, int k)  
  2. {  
  3.    if(pRoot == NULL || k < 1)  
  4.         return 0;  
  5.     if(k == 1)  
  6.         

    相關推薦

    試題彙總

    樹是一種比較重要的資料結構,尤其是二叉樹。二叉樹是一種特殊的樹,在二叉樹中每個節點最多有兩個子節點,一般稱為左子節點和右子節點(或左孩子和右孩子),並且二叉樹的子樹有左右之分,其次序不能任意顛倒。二叉樹是遞迴定義的,因此,與二叉樹有關的題目基本都可以用遞迴思想解決,當然有些題

    C++試題

    else 子節點 typename data fad pub struct char s[] 前序遍歷 #include <iostream> #include <stack> #include <queue> usi

    試題

    題目:輸入兩棵二叉樹A和B,判斷樹B是不是A的子結構 先判斷兩棵二叉樹任一都不為NULL 遞迴判斷:如果當前結點值相等,就判斷左子樹和右子樹是否是子結構 [cpp] view plain copy print? bool IsChildTree(Node * father, Node * so

    重建——面試題6《劍指offer》

    題目描述:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。  /** * Def

    試題的遍歷方式

    一、基本概念 1、二叉樹的概念 一棵二叉樹是結點的一個有限集合,該集合或者為空,或者是由一個根節點加上兩棵分別稱為左子樹和右子樹的二叉樹組成(即一個根節點最多隻有兩個孩子結點)。 2、二叉樹的特點 (1)每個結點最多有兩棵子樹,即二叉樹不存在度大於2的結

    試題(一)---判斷兩個結構是否相同

    一、首先這個問題是判斷二叉樹的結構是否相同,所以這就和二叉樹的資料的值無關。只需要判斷結構;判斷兩個二叉樹的結構是否相同很簡單。 採用遞迴的思想: (1)如果兩棵二叉樹都為空,返回真 (2)

    試題總結(Java)

    本文參考部落格:http://www.jianshu.com/p/0190985635eb 先上二叉樹的資料結構: class TreeNode{ int val; //左孩子 TreeNode left; //右孩子 TreeNo

    試題--已知的兩種遍歷序列,求出另一種遍歷序列

    已知先序遍歷序列和中序遍歷序列,求出後序序列   或者   已知中序序列和後序序列 , 求出先序遍歷。。都是一些考試中容易考的題目。 經過研究發現,已知先序序列和後序序列,無法唯一確定一棵樹,所以就無

    輕鬆搞定試題

    樹是一種比較重要的資料結構,尤其是二叉樹。二叉樹是一種特殊的樹,在二叉樹中每個節點最多有兩個子節點,一般稱為左子節點和右子節點(或左孩子和右孩子),並且二叉樹的子樹有左右之分,其次序不能任意顛倒。二叉樹是遞迴定義的,因此,與二叉樹有關的題目基本都可以用遞迴思想解決

    試題

    import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.uti

    常見的試題

        面試中,最常見是資料結構就是二叉樹和連結串列了,其中和二叉樹有關的常見面試題主要是:樹的前序遍歷、中序遍歷、後序遍歷、分層遍歷、樹的節點數、樹的葉子節點數、樹的第K層節點數、樹的深度、樹的寬度、平衡二叉樹的判定、完全二叉樹的判定、滿二叉樹的判定、由前序中序反推後序遍

    試題

    1. 前序/中序/後序遍歷(非遞迴) 前序 void PrevOrderNonR() { stack<Node*> s; Node* cur =

    【資料結構】---------試題(具體的所有實現)

    實現二叉樹的相關的操作: 先序遍歷樹(遞迴) 中序遍歷樹(遞迴) 後序遍歷樹(遞迴) 層序遍歷樹 建立一棵樹 樹的銷燬 樹的拷貝 二叉樹中節點的個數 二叉樹葉子節點的個數 二叉樹第K層節點的個數 樹的高度 在二叉樹中查詢節點 找當前節點的左子樹

    【資料結構】試題總結

    為了對二叉樹的知識進行鞏固,今天我們來解析5道二叉樹的經典面試題。 這五道面試題如下: 求二叉樹中最遠兩個結點的距離; 判斷一棵樹是否是完全二叉樹; 由前序和中序遍歷序列重建二叉樹 (前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6

    試題:前中序求後序、中後序求前序

    在面試時,避免不了的會遇到一些資料結構的面試題,今天我們就來了解一下二叉樹的經典面試題: 已知二叉樹的前序遍歷順序為ABCDEGHF,中序遍歷順序為DBAGEHCF,求該二叉樹的後序遍歷。 還有: 已知二叉樹的中序遍歷順序為DBAGEHCF,後序遍歷順序為DBGHEFCA,求該二叉樹的前序遍歷。 類似

    騰訊2017暑假試題-查詢的根

    /* 騰訊2017暑假筆試題-查詢二叉樹的根 對於一個高度為k的滿排序二叉樹,給定k和三個數, 找到這三個數的最小根節點 */ #include <iostream> #include <vector> #include <algorithm> u

    相關的演算法試題

    1. 二叉搜尋樹(BST)的後序遍歷序列 2. 序列化/反序列化二叉樹 3. 找到BST中的第k小的數 4. 二叉搜尋樹轉雙鏈表 5. 找出所有節點和滿足目標數的路徑 6.根據二叉樹的前序遍歷和中序遍歷陣列來重建二叉樹 7

    的簡單面試題彙總

    目錄 1.遞迴 2.非遞迴 1.遞迴 2.非遞迴 1.遞迴 2.非遞迴 1.搜尋樹 2.三叉鏈 1.前中後序遍歷(遞迴與非遞迴) 1.前序遍歷 1.遞迴 void preO

    c++實現試題(1)

    1.建立二叉樹2.前序遍歷<遞迴與非遞迴> 3.中序遍歷<遞迴與非遞迴> 4.後序遍歷<遞迴與非遞迴> 5.層次遍歷  6.獲得節點葉子的個數7.二叉樹獲得的高度8.二叉樹交換的左右兒子9.求兩個節點pNode1和pNode2在以[R為樹

    阿里14試題-求一個最大值和最小值的差值絕對值

    阿里巴巴面試題: 輸入:一個二叉樹 輸出:二叉樹的最大值和最小值的差值絕對值 單純從演算法功能上來看 1-可以先建立一個大根堆,把最大的元素挑出來; 2-然後在建立小根堆,把最小的元素挑出來; 3-在求最大和最小差值的絕對值; 程式碼: #if 0 /* 最大堆排序 */