日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

刷题:二叉树的遍历方式及根据遍历结果还原二叉树

發布時間:2023/11/27 生活经验 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 刷题:二叉树的遍历方式及根据遍历结果还原二叉树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二叉樹的遍歷方式及根據遍歷結果還原二叉樹

  • 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;
}

實驗結果:

總結

以上是生活随笔為你收集整理的刷题:二叉树的遍历方式及根据遍历结果还原二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。