1. 程式人生 > >利用棧結構實現二叉樹的非遞迴遍歷,求二叉樹深度、葉子節點數、兩個結點的最近公共祖先及二叉樹結點的最大距離

利用棧結構實現二叉樹的非遞迴遍歷,求二叉樹深度、葉子節點數、兩個結點的最近公共祖先及二叉樹結點的最大距離

原文地址:http://blog.csdn.net/forbes_zhong/article/details/51227747

利用棧實現二叉樹的非遞迴遍歷,並求二叉樹的深度、葉子節點數、兩個節點的最近公共祖先以及二叉樹結點的最大距離,部分參考《劍指offer》這本書,其程式碼如下:

  1. #include<iostream>
  2. #include<vector>
  3. #include<stack>
  4. usingnamespace std;  
  5. typedefstruct BiNode //定義一棵二叉樹
  6. {  
  7.     char val;  
  8.     struct BiNode *left;  
  9.     struct BiNode *right;  
  10.     BiNode(char x) :val(x), left(NULL), right(NULL){}  
  11. }BiNode,*BiTree;  
  12. void CreateBiTree(BiTree &T)//前序建立一顆二叉樹
  13. {  
  14.     char c;  
  15.     cin >> c;  
  16.     if ('#' == c)  
  17.         T=NULL;  
  18.     else
  19.     {  
  20.         T = (BiNode* ) malloc(sizeof(BiNode));  
  21.         T->val = c;  
  22.         CreateBiTree(T->left);  
  23.         CreateBiTree(T->right);  
  24.     }  
  25. }  
  26. //二叉樹的非遞迴遍歷(前序、中序、後序及層序)
  27. void PreOrder(BiTree& T)//前序遍歷,非遞迴
  28. {  
  29.     if (T == NULL)  
  30.         return;  
  31.     vector<BiNode*> S;  
  32.     BiNode *p = T;  
  33.     while (p != NULL || !S.empty())  
  34.     {  
  35.         while
     (p != NULL)  
  36.         {  
  37.             cout << p->val << " ";  
  38.             S.push_back(p);  
  39.             p = p->left;  
  40.         }  
  41.         if (!S.empty())  
  42.         {  
  43.             p = S[S.size() - 1];  
  44.             S.pop_back();  
  45.             p = p->right;  
  46.         }  
  47.     }  
  48.     cout << endl;  
  49. }  
  50. void InOrder(BiTree& T)//中序遍歷,非遞迴
  51. {  
  52.     if (T == NULL)  
  53.         return;  
  54.     vector<BiNode*> S;  
  55.     BiNode *p = T;  
  56.     while ( p != NULL || !S.empty())  
  57.     {  
  58.         while (p != NULL)  
  59.         {  
  60.             S.push_back(p);  
  61.             p = p->left;  
  62.         }  
  63.         if (!S.empty())  
  64.         {  
  65.             p = S[S.size() - 1];  
  66.             cout << p->val << " ";  
  67.             S.pop_back();  
  68.             p = p->right;  
  69.         }  
  70.     }  
  71.     cout << endl;  
  72. }  
  73. void PostOrder(BiTree &T)//後序遍歷(雙棧法),非遞迴
  74. {  
  75.     if (T == NULL)  
  76.         return;  
  77.     vector<BiNode*> S1,S2;  
  78.     BiNode *p ;//當前指標所在結點
  79.     S1.push_back(T);  
  80.     while (!S1.empty())  
  81.     {  
  82.         p = S1[S1.size() - 1];  
  83.         S1.pop_back();  
  84.         S2.push_back(p);  
  85.         if (p->left)  
  86.             S1.push_back(p->left);  
  87.         if (p->right)  
  88.             S1.push_back(p->right);  
  89.     }  
  90.     while (!S2.empty())  
  91.     {  
  92.         cout << S2[S2.size() - 1]->val << " ";  
  93.         S2.pop_back();  
  94.     }  
  95.     cout << endl;  
  96. }  
  97. void LevelOrder(BiTree &T)//非遞迴層序遍歷,可選擇按層輸出結點,也可用於計算二叉樹的深度
  98. {  
  99.     if (T == NULL)  
  100.         return;  
  101.     vector<BiNode*> S;  
  102.     S.push_back(T);  
  103.     //int depth = 0;//統計二叉樹的深度
  104.     int cur = 0;  
  105.     int last = 1;  
  106.     while (cur < S.size())  
  107.     {  
  108.         last = S.size();  
  109.         while (cur < last)  
  110.         {  
  111.             cout << S[cur]->val << " ";  
  112.             if (S[cur]->left != NULL)  
  113.                 S.push_back(S[cur]->left);  
  114.             if (S[cur]->right != NULL)  
  115.                 S.push_back(S[cur]->right);  
  116.             ++cur;  
  117.         }  
  118.         //cout << endl;如果需要按層輸出每一層的結點則取消此行註釋
  119.         //depth++;//如果要求二叉樹的深度,只需在此統計輸出了多少次endl就可以
  120.     }  
  121.     cout << endl;  
  122. }  
  123. void LevelOrder2(BiTree &T)//層序遍歷,非遞迴(雙棧法),奇偶層數儲存有區別時可實現之字形列印
  124. {  
  125.     if (T == NULL)  
  126.         return;  
  127.     stack<BiNode*> Levels[2];  
  128.     int cur = 0;//奇數行
  129.     int next = 1;//偶數行
  130.     Levels[cur].push(T);  
  131.     while (!Levels[0].empty() || !Levels[1].empty())  
  132.     {  
  133.         BiNode *p = Levels[cur].top();  
  134.         Levels[cur].pop();  
  135.         cout << p->val << " ";  
  136.         if (cur == 0)//奇數層順序儲存
  137.         {  
  138.             if (p->left != NULL)  
  139.                 Levels[next].push(p->left);  
  140.             if (p->right != NULL)  
  141.                 Levels[next].push(p->right);  
  142.         }  
  143.         else//偶數層逆序儲存
  144.         {  
  145.             if (p->right != NULL)  
  146.                 Levels[next].push(p->right);  
  147.             if (p->left != NULL)  
  148.                 Levels[next].push(p->left);  
  149.         }  
  150.         if (Levels[cur].empty())  
  151.         {  
  152.             //cout << endl;//換行,如果不換行可以註釋掉這條
  153.             cur = 1 - cur;  
  154.             next = 1 - next;  
  155.         }  
  156.     }  
  157.     cout << endl;  
  158. }  
  159. void GetNodePath(BiNode* T, BiNode* Node, vector<BiNode*>& Path,int &found)//獲取二叉樹中從根節點到指定節點的路徑 
  160. {  
  161.     if (T == NULL)  
  162.         return;  
  163.     Path.push_back(T);  
  164.     if (T == Node)  
  165.         found = 1;  
  166.     if (!found)  
  167.     {  
  168.         GetNodePath(T->left, Node, Path, found);  
  169.     }  
  170.     if (!found)  
  171.     {  
  172.         GetNodePath(T->right, Node, Path, found);  
  173.     }  
  174.     if (!found)  
  175.         Path.pop_back();  
  176.     else
  177.         return;  
  178. }  
  179. BiNode* GetLastCommonNode(

    相關推薦

    利用結構實現深度葉子節點結點最近公共祖先結點距離

    原文地址:http://blog.csdn.net/forbes_zhong/article/details/51227747 利用棧實現二叉樹的非遞迴遍歷,並求二叉樹的深度、葉子節點數、兩個節點的最近公共祖先以及二叉樹結點的最大距離,部分參考《劍指offer》這本書

    Java實現

    二叉樹的前序、中序和後序遍歷可以採用遞迴和非遞迴的方法實現,遞迴的方法邏輯簡單清晰,易於理解,但遞迴的方法需要使用額外的棧空間,執行效率較低。而非遞迴的方法則效率較高。 下面是相應的Java實現: 前序遍歷(非遞迴實現): public static void pre

    資料結構(四)之

    void Inoder(Bitree root)//二叉樹的中序遍歷非遞迴 { IniStack(&S);//初始化一個棧 p=root; while(!isEmpty(S)||p!=NULL) { if(p!=NULL)//如果當前結點不為空進棧 { pu

    先序後序建立前中後序層次以及統計葉子結點個數以及深度

    下面的程式碼實現了二叉樹的先序或者後序遞迴建立,然後實現了二叉樹的非遞迴的先序中序後序遍歷,還有層次遍歷,以及統計樹的葉子結點個數和樹的深度。其中非遞迴的先中後序遍歷用到了鏈棧,層次遍歷用到了佇列。 程式設計平臺為Visual Studio 2012,語言為C,但不是純C,

    c++實現

    三種遍歷演算法均採用棧來實現 1.前序遍歷:先訪問根節點,再訪問左子樹,最後訪問右子樹 先將根節點進棧,棧不空時迴圈:{出棧tmp,訪問tmp,若其右子樹節點不空則將tmp的右孩子節點進棧,若其左孩子節點不空則將tmp的左孩子節點進棧。} 2.中序遍歷演算法:左中右 從根節

    用Python實現繪製

    前言 關於二叉樹的實現與遍歷,網上已經有很多文章了,包括C, C++以及JAVA等。鑑於python做為指令碼語言的簡潔性,這裡寫一篇小文章用python實現二叉樹,幫助一些對資料結構不太熟悉的人快速瞭解下二叉樹。本文主要通過python以非遞迴形式實現二叉樹

    資料結構篇卷三 -- (With Java)

    Nonrecursive Traversal of Binary Tree First I wanna talk about why should we use <code>Stack</code> to implement this algorithm. I think it is

    的通用演算法

    二叉樹的3中遍歷策略,關鍵在於處理節點的時機不同:前序遍歷是遇到節點時處理,中序是處理完左節點後再處理,而後序是在處理完左右節點後再處理。 使用非遞迴方法實現時,除了記錄當前的節點的訪問棧,還需要記錄當前節點的狀態。對於每一個節點,我們用0來表示尚未處理左右子節點,1表示僅僅處理完畢左節點,2表

    (★★★) (統一的解決思路)

    轉載:【刷題】二叉樹非遞迴遍歷   stack<Node*> st; void preOrder(Node* root) { Node *cur = root; while (cur || !st.empty()) { while (

    C++ (別貪心一次迴圈訪問一個節點前序2例外)

    前序遍歷方法1: void preOrder1(BiNode * rootN) { if (rootN != nullptr) { stack<BiNode*> nodeSta; nodeSta.push(rootN); BiNode* curNode; wh

    C++

    前序遍歷方法1: void preOrder1(BiNode * rootN) { if (rootN != nullptr) { stack<BiNode*> nodeSta;

    方法總結

    以前只會二叉樹的一種非遞迴遍歷,最近又看了二叉樹的多種非遞迴遍歷方式,感覺很有用,親自實現用理解了一番,總結如下。 一、常用方式 1、先序遍歷 1.1 自己常用的一種方式: public List<Integer> preOrder1(TreeNode r

    層次反轉輸出路徑等常見操作詳細總結

    1.序言 在實際工作中,很多業務場景其實也需要一些比較巧妙的演算法來支撐,並不是業務邏輯就全是複製貼上或者說重複的程式碼寫一百遍。越是隨著演算法研究的深入,越是發現數據結構的重要性。或者說,資料結構中就蘊藏著無數精妙演算法的思想,很多演算法的思想在資料結構中體現得非常突出。而作為一種

    二叉樹資料結構 public class TreeNode{ int val; TreeNode left; TreeNode right; TreeNode(int value){ val = value;

    (三種+層序)

    #include <iostream> #include <stdio.h> #include <queue> #include <stack> using namespace std; typedef struct BiTN

    基本演算法以及高度寬度等

    二叉樹基本演算法,遍歷以及求高度、寬度等路徑 轉自Powered by: C++部落格   Copyright © 天一程 //二叉樹的相關演算法,《資料結構習題與解析》7.3 //演算法 49個,程式碼量1200+ ,時間9小時 #include<

    ---->簡潔,容易版.

    後序遍歷(左->右->根):需要一個標記Lastvisited 只有兩種情況才能彈出棧,1.右孩子節點為空,2.右孩子節點已經訪問過(如果沒有這條,那麼會死迴圈再次push該孩子的右節點)

    資料結構--利用輔助

    #include "StdAfx.h" #include <stdio.h> #include <stdlib.h> /*非遞迴方法前序遍歷二叉樹,利用輔助棧(指標陣列實現)。由於對指標不是很熟悉,程式碼較為混亂,基本上實現遍歷的功能。

    資料結構與演算法 -- 鏈式詳解(()/葉子個數深度計算)

    前言 PS:樹型結構是一種重要的非線性資料結構,教科書上一般都是樹與二叉樹,由此可見,樹和二叉樹是有區別和聯絡的,網上有人說二叉樹是樹的一種特殊形式,但經過查資料,樹和二叉樹沒有一個肯定的說法,但唯一可以肯定都是樹型結構。但是按照定義來看二叉樹並不是樹的一種特殊形式(下面解釋)。樹型資料結構的作

    ---JAVA實現

            二叉樹的遞迴遍歷方式是很簡單的,當需要用非遞迴的方式遍歷時,就需要藉助棧這種資料結構,以前序遍歷為例,其定義為先訪問根節點,再以前序方式訪問左子樹,再以前序遍歷方式訪問右子樹,這是個遞迴的定義。對於前序遍歷,最先訪問的是根,然後是根左邊的孩子,