刷题:二叉树的遍历方式及根据遍历结果还原二叉树
二叉樹的遍歷方式及根據遍歷結果還原二叉樹
- 1. 二叉樹的遍歷方式
- 2. 根據遍歷結果還原二叉樹
- 2.1 已知先序遍歷和中序遍歷還原二叉樹
- 2.2 已知后序遍歷和中序遍歷還原二叉樹
- 實驗代碼:
1. 二叉樹的遍歷方式
二叉樹有三種遍歷方式:先序遍歷、中序遍歷、后序遍歷。
先序遍歷: a、訪問根節點;b、前序遍歷左子樹;c、前序遍歷右子樹。
中序遍歷: a、中序遍歷左子樹;b、訪問根節點;c、中序遍歷右子樹。
后序遍歷:a、后序遍歷左子樹;b、后續遍歷右子樹;c、訪問根節點。
2. 根據遍歷結果還原二叉樹
已知先序遍歷和中序遍歷,可以還原二叉樹;
已知中序遍歷和后序遍歷,可以還原二叉樹;
已知先序遍歷和后序遍歷,不可以還原二叉樹。
2.1 已知先序遍歷和中序遍歷還原二叉樹
思路:
1)、根據先序遍歷結果確定根節點。
先序遍歷的第一個節點為根節點。
2)、在中序遍歷結果中找到根節點,根節點左側的部分為左子樹節點,根節點右側的部分為右子樹節點。
3)、將中序遍歷的結果按根節點分為兩部分,迭代的執行第一步和第二步,直到還原整個二叉樹。
例如:已知先序遍歷的結果為:ABDHIEJKCFLMGNO,中序遍歷的結果為:HDIBJEKALFMCNGO。則二叉樹為以下結構:
其后序遍歷結果為:HIDJKEBLMFNOGCA
2.2 已知后序遍歷和中序遍歷還原二叉樹
思路:
1)、根據后序遍歷結果確定根節點。
后序遍歷的最后一個節點為根節點。
2)、在中序遍歷結果中找到根節點,根節點左側的部分為左子樹節點,根節點右側的部分為右子樹節點。
3)、將中序遍歷的結果按根節點分為兩部分,迭代的執行第一步和第二步,直到還原整個二叉樹。
例如:已知后序遍歷的結果為:HIDJKEBLMFNOGCA,中序遍歷的結果為:HDIBJEKALFMCNGO。則二叉樹為以下結構:
其先序遍歷結果為:ABDHIEJKCFLMGNO
已知前序和中序,后序和中序遍歷序列之后,可以唯一確定一棵二叉樹。但是,只知道前序和后序遍歷序列,是無法知道哪個結點是左子樹還算右子樹。
實驗代碼:
#include <iostream>
#include <vector>
#include "Tree.h"
using namespace std;
//************************************
// 函數名稱:CreateBinaryTree
// 函數功能:構建二叉樹
// 返 回 值:無
// 參 數:二叉樹根節點引用、元素指針的引用,元素個數的引用
// 函數說明:該函數根據一組元素數據構建二叉樹。由于僅僅利用利用一組數據不能推斷二叉樹的結構,
// 因此需要在元素數組中加入#來表示某個空節點。此外該函數以先序遍歷的方式構建二叉樹。
// 由于該函數需要遞歸調用并且需要改變參數的值,因此參數均為引用的形式。
//************************************ /
void CreateBinaryTree(BiTree &T, ElementPtr &p ,int &num)
{if ('#' == *p || num == 0) //當遇到#時,令樹的根節點為NULL,從而結束該分支的遞歸{T = NULL;num--; p++;} else{T = new TreeNode;T->data = *p;num--; p++;CreateBinaryTree(T->Lchild, p, num);CreateBinaryTree(T->Rchild, p, num);}}
//************************************
// 函數名稱:CreateBinaryTree
// 函數功能:構建二叉樹
// 返 回 值: 無
// 參 數:二叉樹根節點引用、先序遍歷數組引用、中序遍歷數組引用
// 函數說明:該函數根據先序遍歷結果和中序遍歷結果構建二叉樹
//************************************ /
void CreateBinaryTree(BiTree &T,vector<ElementType> & PreOrder, vector<ElementType> & MidOrder)
{if (PreOrder.size() == 0 || MidOrder.size() == 0){T = NULL;return;}if (PreOrder.size() != MidOrder.size()){T = NULL;return;}vector<ElementType> PreOrder_L, PreOrder_R, MidOrder_R, MidOrder_L;int root_index;int len = PreOrder.size();T = new TreeNode;T->data = PreOrder[0];for (int i = 0; i < len; ++i){if (MidOrder[i] == PreOrder[0]){root_index = i;break;}}for (int i = 0; i < root_index; ++i){MidOrder_L.push_back(MidOrder[i]);PreOrder_L.push_back(PreOrder[i + 1]);}for (int i = root_index + 1; i < len; ++i){MidOrder_R.push_back(MidOrder[i]);PreOrder_R.push_back(PreOrder[i]);}CreateBinaryTree(T->Lchild ,PreOrder_L, MidOrder_L);CreateBinaryTree(T->Rchild,PreOrder_R, MidOrder_R);}
//************************************
// 函數名稱:BiTreeDepth
// 函數功能:計算二叉樹深度
// 返 回 值: 無
// 參 數:二叉樹根節點
// 函數說明:計算二叉樹深度,遞歸調用
//************************************ /
int BiTreeDepth(BiTree T)
{int Ldepth, Rdepth;if (T == NULL)return 0;else{Ldepth = BiTreeDepth(T->Lchild);Rdepth = BiTreeDepth(T->Rchild);}return Ldepth > Rdepth ? Ldepth + 1 : Rdepth + 1;}
//************************************
// 函數名稱:PreTraverse
// 函數功能:先序遍歷
// 返 回 值:無
// 參 數:二叉樹根節點
// 函數說明:二叉樹的先序遍歷
//************************************ /
void PreTraverse(BiTree T)
{if (T){cout << T->data << " ";PreTraverse(T->Lchild);PreTraverse(T->Rchild);}
}
//************************************
// 函數名稱:MidTraverse
// 函數功能:中序遍歷
// 返 回 值: 無
// 參 數:二叉樹根節點
// 函數說明:二叉樹的中序遍歷
//************************************ /
void MidTraverse(BiTree T)
{if (T){MidTraverse(T->Lchild);cout << T->data << " ";MidTraverse(T->Rchild);}
}
//************************************
// 函數名稱:PostTracerse
// 函數功能:后序遍歷
// 返 回 值: 無
// 參 數:二叉樹根節點
// 函數說明:二叉樹的后序遍歷
//************************************ /
void PostTracerse(BiTree T)
{if (T){PostTracerse(T->Lchild);PostTracerse(T->Rchild);cout << T->data << " ";}
}//主函數
int main()
{//根據一組元素數據構建二叉樹BiTree Root;ElementType src[] = { 'A','B','D','G','#','#','H','#','#','#','C','E','#','I','#','#','F','#','#' };int num = sizeof(src);ElementType* p = src;CreateBinaryTree(Root,p,num);//構建完二叉樹后p會改變,該問題待優化cout << "PreTraverse: ";PreTraverse(Root);cout << endl;cout << "MidTraverse: ";MidTraverse(Root);cout << endl;cout << "PostTracerse:";PostTracerse(Root);cout << endl;cout << "The Tree Depth: " << BiTreeDepth(Root) <<endl<<endl;//根據先序遍歷結果和中序遍歷結果構建二叉樹BiTree Root2;vector<ElementType> Pre = { 'A','B','D','G','H','C','E','I','F' };vector<ElementType> Mid = { 'G','D','H','B','A','E','I','C','F' };CreateBinaryTree(Root2,Pre, Mid);cout << "PreTraverse: ";PreTraverse(Root2);cout << endl;cout << "MidTraverse: ";MidTraverse(Root2);cout << endl;cout << "PostTracerse:";PostTracerse(Root2);cout << endl;cout << "The Tree Depth: " << BiTreeDepth(Root2) << endl << endl;//根據一組元素數據構建二叉樹對象p = src;int num2 = sizeof(src);BinaryTree tree(p, num2);cout << "PreTraverse: ";tree.PreTraverse();cout << endl;cout << "MidTraverse: ";tree.MidTraverse();cout << endl;cout << "PostTracerse:";tree.PostTracerse();cout << endl;cout << "The Tree Depth: " << tree.TreeDepth() << endl<<endl;//根據先序遍歷結果和中序遍歷結果構建二叉樹對象BinaryTree tree2(Pre,Mid);cout << "PreTraverse: ";tree2.PreTraverse();cout << endl;cout << "MidTraverse: ";tree2.MidTraverse();cout << endl;cout << "PostTracerse:";tree2.PostTracerse();cout << endl;cout << "The Tree Depth: " << tree.TreeDepth() << endl << endl;return 0;
}
實驗結果:
總結
以上是生活随笔為你收集整理的刷题:二叉树的遍历方式及根据遍历结果还原二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王者荣耀墨子进击墨子号什么时候返场 多少
- 下一篇: ORB_SLAM2代码阅读(1)——系统