C++資料結構:二叉樹(二)——二叉樹的遍歷
一、序言
在上一篇文章中《二叉樹的先序建立》,我們介紹了二叉樹的基本結構以及先序建立二叉樹,在本篇文章中,我們要對二叉樹進行遍歷,包括:
- 層序遍歷
- 遞迴先序遍歷、遞迴中序遍歷、遞迴後序遍歷
- 非遞迴中序遍歷
二、二叉樹的遍歷
BiTree.h 標頭檔案新增定義如下,其餘部分不變,請參考《二叉樹的先序建立》:
class BiTree
{
public:
void LevelOrder(); //層序遍歷
void PreOrder(); //先序遞迴遍歷二叉樹
void InOrder(); //中序遞迴遍歷二叉樹
void PostOrder(); //後序遞迴遍歷二叉樹
void InOrder2(); //中序非遞迴遍歷二叉樹
};
BiTree.cpp 檔案新增定義如下,其餘部分不變
#include "BiTree.h"
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
static void LevelTraverse(BiTNode *ptree); //層序遍歷二叉樹
static void PreTraverse(BiTNode *ptree); //遞迴先序遍歷二叉樹
static void InTraverse(BiTNode *ptree); //遞迴中序遍歷二叉樹
static void PostTraverse(BiTNode *ptree); //遞迴後序遍歷二叉樹
static void visit(BiTNode *ptree); //列印資料
//操作: 層序遍歷二叉樹
//操作前:無引數
//操作後:打印出層序遍歷結果
void BiTree::LevelOrder()
{
cout << "層序遍歷二叉樹:" ;
if (this->root != nullptr)
LevelTraverse(this->root); //呼叫層序遍歷二叉樹函式
else
cout << "二叉樹為空" << endl;
cout << endl;
}
static void LevelTraverse(BiTNode *ptree)
{
/*
1.構造輔助佇列(我們將直接使用queue庫中提供的函式)
2.先將二叉樹的根節點入隊,然後出隊,訪問該節點
3.如果它有左子樹,則將左子樹根節點入隊
4.如果它有右子樹,則將右子樹根節點入隊
5.出隊,訪問出隊節點,如此反覆,直到佇列為空
*/
queue<BiTNode *> BiTNodeQueue; //佇列型別是指向節點的指標型別
BiTNodeQueue.push(ptree); //指向頭節點的指標入隊
while (!BiTNodeQueue.empty()) //佇列不為空
{
BiTNode *FrontNode = BiTNodeQueue.front(); //隊首元素
visit(FrontNode); //訪問隊首元素
BiTNodeQueue.pop(); //隊首元素出隊
if (FrontNode->lchild != nullptr) //如果隊首元素這個指標有左孩子則讓其入佇列
BiTNodeQueue.push(FrontNode->lchild);
if (FrontNode->rchild != nullptr) //如果隊首元素這個指標有右孩子則讓其入佇列
BiTNodeQueue.push(FrontNode->rchild);
}//while
}
//操作: 先序遞迴遍歷二叉樹
//操作前:無引數
//操作後:打印出先序遍歷結果
void BiTree::PreOrder()
{
cout << "先序遍歷二叉樹:";
if (this->root != nullptr)
PreTraverse(this->root); //呼叫先序遍歷二叉樹函式
else
cout << "二叉樹為空" << endl;
cout << endl;
}
static void PreTraverse(BiTNode *ptree)
{
if (ptree != nullptr)
{
visit(ptree);
PreTraverse(ptree->lchild);
PreTraverse(ptree->rchild);
}
}
//操作: 中序遞迴遍歷二叉樹
//操作前:無引數
//操作後:打印出中序遍歷結果
void BiTree::InOrder()
{
cout << "中序遍歷二叉樹:";
if (this->root != nullptr)
InTraverse(this->root); //呼叫中序遍歷二叉樹函式
else
cout << "二叉樹為空" << endl;
cout << endl;
}
static void InTraverse(BiTNode *ptree)
{
if (ptree != nullptr)
{
InTraverse(ptree->lchild);
visit(ptree);
InTraverse(ptree->rchild);
}
}
//操作: 後序遞迴遍歷二叉樹
//操作前:無引數
//操作後:打印出後序遍歷結果
void BiTree::PostOrder()
{
cout << "後序遍歷二叉樹:";
if (this->root != nullptr)
PostTraverse(this->root); //呼叫後序遍歷二叉樹函式
else
cout << "二叉樹為空" << endl;
cout << endl;
}
static void PostTraverse(BiTNode *ptree)
{
if (ptree != nullptr)
{
PostTraverse(ptree->lchild);
PostTraverse(ptree->rchild);
visit(ptree);
}
}
//操作: 中序非遞迴遍歷二叉樹
//操作前:無引數
//操作後:打印出中序遍歷結果
void BiTree::InOrder2()
{
cout << "中序非遞迴遍歷二叉樹:";
if (this->root != nullptr)
{
stack<BiTNode *> BiTNodeStack;
BiTNode *ptree = this->root;
while (ptree != nullptr || !BiTNodeStack.empty()) //棧不為空或者ptree不為空時則迴圈
{
if (ptree != nullptr) //每當根節點不為空時
{
BiTNodeStack.push(ptree); //根節點入棧
ptree = ptree->lchild; //ptree指向左子樹的根,遍歷左子樹
}
else //每當根節點為空,說明左子樹到頭了
{
BiTNode *TopStack = BiTNodeStack.top(); //當前棧頂元素為最左節點
visit(TopStack); //訪問棧頂元素
BiTNodeStack.pop(); //棧頂元素出棧,出棧後的新棧頂元素為剛出棧元素的根節點
ptree = TopStack->rchild; //遍歷剛出棧元素的右子樹
}
}//while
}
else
cout << "二叉樹為空" << endl;
cout << endl;
}
static void visit(BiTNode *ptree)
{
cout << ptree->data << " ";
}
BiTree.cpp 檔案定義如下
#include "BiTree.h"
#include <iostream>
using namespace std;
int main()
{
BiTree tree;
tree.CreateBiTree(); //先序建立二叉樹
tree.GetBiTRoot(); //獲取二叉樹的根節點資料
tree.GetBiTNum(); //獲取二叉樹的總節點個數
tree.GetBiTDepth(); //獲取二叉樹的深度
tree.LevelOrder(); //二叉樹的層序遍歷
tree.PreOrder(); //二叉樹的遞迴先序遍歷
tree.InOrder(); //二叉樹的遞迴中序遍歷
tree.InOrder2(); //二叉樹的非遞迴中序遍歷
tree.PostOrder(); //二叉樹的遞迴後序遍歷
system("pause");
return EXIT_SUCCESS;
}
三、執行結果
輸入二叉樹如下圖所示
執行結果
如有不對的地方歡迎大家指正交流
相關推薦
《 常見演算法與資料結構》符號表ST(4)——二叉查詢樹刪除 (附動畫)
符號表ST(4)——二叉查詢樹刪除 (附動畫) 本系列文章主要介紹常用的演算法和資料結構的知識,記錄的是《Algorithms I/II》課程的內容,採用的是“演算法(第4版)”這本紅寶書作為
演算法題(三十一):二叉搜尋樹(BST)的後序遍歷序列
題目描述 輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的陣列的任意兩個數字都互不相同。 分析 後序遍歷序列中,最右邊數字也就是根結點,會把數集分為左右兩部分,左邊數集都小於root,右邊數集都大於root。左
C#資料結構與算法系列(十):逆波蘭計算器——逆波蘭表示式(字尾表示式)
1.介紹 字尾表示式又稱逆波蘭表示式,與字首表示式相似,只是運算子位於運算元之後 2.舉例說明 (3+4)*5-6對應的字尾表示式就是3 4 +5 * 6 - 3.示例 輸入一個逆波蘭表示式(字尾表示式),使用棧(Stack),計算其結果 思路分析: 從左至右掃描表示式,遇到數字時,將數字壓入堆疊,遇到運算
二叉樹(14)----由前序遍歷和中序遍歷重建二叉樹,遞迴方式
相關連結: 1、二叉樹定義 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeN
PTA 資料結構與演算法題目集(中文)5-3 樹的同構 (25分)
#include <stdio.h> #include <string.h> /* 題目以26個大寫字母為結點值,可以建立一個26*2的二維陣列 表示結點以及結點的左右結點 若只有一個結點,則判斷兩根是否相同 若有多節點,則先將前一棵樹的結點的左右結
java實現二叉搜尋樹(BST)包含增刪和遍歷操作
二叉搜尋樹基本知識可以看演算法導論第三版163頁,也可以百度搜索下,程式碼如下: package com.ma.al.binaryTree; /** * @author xiaoma * */ public class MyBinarySearchTree {
C++資料結構:二叉樹(一)——先序建立二叉樹
一、二叉樹 (Binary Tree) 定義: 二叉樹是n個節點的有限集合,該集合或者為空集( 稱為空二叉樹 ),或者由一個根節點和兩棵互不相交的的二叉樹組成,這兩棵二叉樹分別稱為根節點的左子樹和右
C++資料結構:二叉樹(二)——二叉樹的遍歷
一、序言 在上一篇文章中《二叉樹的先序建立》,我們介紹了二叉樹的基本結構以及先序建立二叉樹,在本篇文章中,我們要對二叉樹進行遍歷,包括: 層序遍歷 遞迴先序遍歷、遞迴中序遍歷、遞迴後序遍歷 非遞迴中序遍歷 二、二叉樹的遍歷 BiTree.h
Java資料結構:前序和中序還原二叉樹
根據二叉樹前根中根遍歷出來的陣列還原二叉樹。 前根:ABDGCEFH 中跟:DGBAECHF 上程式碼: private BinaryNode<T> create(T[] prelist, T
PTA資料結構與演算法題目集(中文)4-12 二叉搜尋樹的操作集 (30分)
本題要求實現給定二叉搜尋樹的5種常用操作。 函式介面定義: BinTree Insert( BinTree BST, ElementType X ); BinTree Delete( BinTree BST, ElementType X ); Position Fin
PTA 資料結構與演算法題目集(中文) 6-9 二叉樹的遍歷
6-9 二叉樹的遍歷(25 分)本題要求給定二叉樹的4種遍歷。函式介面定義:void InorderTraversal( BinTree BT ); void PreorderTraversal( Bi
PTA資料結構與演算法題目集(中文)4-9 二叉樹的遍歷 (25分)
本題要求給定二叉樹的4種遍歷。 函式介面定義: void InorderTraversal( BinTree BT ); void PreorderTraversal( BinTree BT ); void PostorderTraversal( BinTree BT
資料結構——樹(8)——二叉搜尋樹的插入和刪除操作
二叉搜尋樹的插入操作 我們要在二叉搜尋樹中執行各種操作的前提就是,我們首先要有一棵二叉搜尋樹。那麼,如何建立一棵二叉搜尋樹呢?最簡單的方法就是我們可以從一棵空樹開始,每次呼叫一個addNode函式,將一個新的值插入二叉搜尋樹中。但是在每次插入的時候我們都要保持
資料結構——樹(7)——二叉搜尋樹及其操作原理
二叉樹與二叉搜尋樹 在之前的文章中,我們提到過三叉樹,n叉樹,但是我們實際用的最多卻是二叉樹,因為這樣的結構更適合我們程式設計和更適合我們使用遞迴的方式。所以我們可以限制孩子的數量使得生成的樹更容易實施。那麼怎麼定義二叉樹呢? - 樹中的每個節點至多有兩個孩
資料結構之樹(三)——二叉樹定義和性質
二叉樹(Binary Tree)是n(n>=0)個結點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根結點和倆棵互不相交的,分別稱為根結點的左子樹和右子樹的二叉樹組成。 如圖: 二叉樹的特點 二叉樹的特點: 1.每個結點最多有倆棵子樹,所以二叉樹中不存在度
[C++]資料結構:散列表(雜湊表)、雜湊函式構造、處理雜湊衝突
關鍵字{12,25, 38, 15, 16, 29, 78, 67, 56, 21, 22, 47 } , 對應後位置是 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}。 不過這種方法很容易產生衝突(如果關鍵字餘數大部分相同)。一般地,散列表長為m, 通常p
樹(7)-----二叉樹的序列化和反序列化
層次 not oot return end else none In bsp 1、序列化:層次遍歷【用字符串來存儲】 2、反序列化:用隊列存已經建立的節點,從序列化後的字符串列表取數來建立樹 def serialize(self, root): "
二叉樹(0)——二叉樹的實現與二叉樹的遍歷
0.二叉樹的實現(C++) 未完,待補充 #include <iostream> #include<iostream> #include<queue> #include<stack> using namespace std; //二叉樹結點的
二叉樹的深度優先遍歷(DFS)與廣度優先遍歷(BFS)
最近在練習劍指offer上的題,討論區看到有人提到深度優先遍歷和廣度優先遍歷,就查了一點相關知識點。 深度優先遍歷(Depth First Search,簡稱DFS)又稱深度優先搜尋,遍歷的過程是 從某個頂點出發,首先訪問這個頂點,然後找出剛訪問這個結點的第一個未被訪問的鄰結點,然後
資料結構:雜湊表(Hash Table)
雜湊表定義 雜湊表是一種根據關鍵碼去尋找值的資料對映結構,該結構通過把關鍵碼對映的位置去尋找存放值的地方。 本質是一個數組,陣列中每一個元素稱為一個箱子(bin),箱子中存放的是鍵值對。 雜湊表的儲存過程如下: 根據 key 計算出它的雜湊值 h。 假設箱子的個數