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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

二叉树的前序、中序、后序遍历与创建

發(fā)布時(shí)間:2023/12/9 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树的前序、中序、后序遍历与创建 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

#include <iostream>
#include <string>
#include <stack>
using namespace std;
struct node;
typedef node *pNode;
struct node {
???? char data;
???? pNode left, right;
};
string line;
string::iterator it;
// 前序擴(kuò)展序列建立二叉樹??
void plant(pNode &root)
{
???? if (it == line.end())
???????? return;
???? char data = *it++;
???? if (data == '/')
???????? root = NULL;
???? else {
???????? root = new node();
???????? root->data = data;
???????? plant(root->left);
???????? plant(root->right);
???? }
}
// 先序遍歷??
void pre_order(pNode root)
{
???? stack<pNode> s;
???? while (root != NULL || !s.empty())
???? {
???????? if (root != NULL) {
???????????? cout << root->data << " ";
???????????? s.push(root);
???????????? root = root->left;
???????? } else {
???????????? root = s.top();
???????????? s.pop();
???????????? root = root->right;
???????? }
???? }
}
// 中序遍歷??
void in_order(pNode root)
{
???? stack<pNode> s;
???? while (root != NULL || !s.empty())
???? {
???????? if (root != NULL) {
???????????? s.push(root);
???????????? root = root->left;
???????? } else {
???????????? root = s.top();
???????????? s.pop();
???????????? cout << root->data << " ";
???????????? root = root->right;
???????? }
???? }
}
// 壓棧的參數(shù)類型,包括局部變量和行號(hào)??
struct stack_arg {
???? stack_arg(pNode _root, int _line)
???? : root(_root), line(_line) { }
???? pNode root;
???? int line;
};
// 后序遍歷??
void post_order(pNode root)
{
???? stack<stack_arg> s;
???? s.push(stack_arg(root, 1));
???? while (!s.empty())
???? {
???????? switch (s.top().line) {
???????? case 1:
???????????? if (s.top().root == NULL)
???????????????? s.pop();
???????????? else
???????????????? s.top().line = 2;
???????????? break;
???????? case 2:
???????????? s.top().line = 3;??
???????????? s.push(stack_arg(s.top().root->left, 1));
???????????? break;
???????? case 3:
???????????? s.top().line = 4;
???????????? s.push(stack_arg(s.top().root->right, 1));
???????????? break;
???????? case 4:
???????????? cout << s.top().root->data << " ";
???????????? s.pop();
???????????? break;
???????? }
???? }
}
int main()
{
???? cin >> line;
???? it = line.begin();
???? pNode root = NULL;
???? plant(root);
???? cout << "先序遍歷" << endl;??
???? pre_order(root);
???? cout << endl;
???? cout << "中序遍歷" << endl;??
???? in_order(root);
???? cout << endl;
???? cout << "后序遍歷" << endl;??
???? post_order(root);
???? cout << endl;
???? system("pause");
???? return 0;
}
/*
input
???? ABDI//J//EK//LQ///CFM//N//GO//P//
output
???? 先序遍歷:
???? A B D I J E K L Q C F M N G O P
???? 中序遍歷
???? I D J B K E Q L A M F N C O G P
???? 后序遍歷??
???? I J D K Q L E B M N F O P G C A

?

//
知樹的前序遍歷,后序遍歷,怎么求中序遍歷?
通過(guò)對(duì)同一棵二叉樹三種遍歷方式的分析,概括出由前序、中序或由中序、后序遍歷結(jié)果快速還原二叉樹的方法。?
二叉樹是最為常用的數(shù)據(jù)結(jié)構(gòu),它的實(shí)際應(yīng)用非常廣泛。二叉樹的遍歷方式有三種,前序遍歷、中序遍歷、后序遍歷。先序遍歷的順序?yàn)?#xff1a;NLR,即先根結(jié)點(diǎn),然后左子樹、右子樹;中序遍歷順序?yàn)?#xff1a;LNR先左子樹,然后根結(jié)點(diǎn)、右子樹;后序遍歷順序?yàn)?#xff1a;LRN先左子樹、然后右子樹、根結(jié)點(diǎn)。由前序和中序遍歷、由中序和后序遍歷序列可以唯一確定一棵二叉樹,而由前序和后序遍歷序列不能唯一確定一棵二叉樹。?
? 二叉排序樹對(duì)二叉樹作了進(jìn)一步的限定:根結(jié)點(diǎn)的權(quán)值大于(或小于)左子樹中所有結(jié)點(diǎn)的權(quán)值;根結(jié)點(diǎn)的權(quán)值小于(或大于)其右子樹中所有結(jié)點(diǎn)的權(quán)值。?
? 那么如何根據(jù)三種遍歷序列之間的關(guān)系及二叉排序樹來(lái)快速還原一棵二叉樹?下面以二叉樹的前序和中序遍歷序列為基礎(chǔ),利用二叉排序樹的性質(zhì),給出快速還原二叉樹的方法。?
? 1由給定前序和中序序列或中序和后序序列還原二叉樹的方法?
? 例:前序序列:ABDECFGH 中序序列:DEBACGFH (后序序列:EDBGHFCA)?
? (1)給中序序列中的每個(gè)結(jié)點(diǎn)從小到大、從左到右賦以權(quán)值,如下:?
? D(1)E(2)B(3)A(4)C(5)G(6)F(7)H(8)?
? (2)還原時(shí)讀入的序列為前序序列,從左到右依次讀入序列中的各個(gè)結(jié)點(diǎn)值和相應(yīng)的權(quán)值; ?
? (3)由讀入的序列,根據(jù)第1)步中給定的權(quán)值按照二叉排序樹的構(gòu)造規(guī)則構(gòu)造二叉排序樹。第一個(gè)讀入的結(jié)點(diǎn)為根結(jié)點(diǎn),其他結(jié)點(diǎn)分別為左右子樹中的結(jié)點(diǎn)。設(shè)根結(jié)點(diǎn)為TT,權(quán)值為NN,當(dāng)前讀入結(jié)點(diǎn)為SS,權(quán)值為MM,若MM
? (4)將SS插入到TT的左子樹或右子樹的過(guò)程中,仍然遵循3)中的規(guī)則,直至左子樹或右子樹為空時(shí)止。?
? (5)讀入序列結(jié)束時(shí),二叉樹還原成功。?
6)對(duì)于由中序序列和后序序列還原二叉樹是,讀入的序列為后序序列,從右向左讀入,構(gòu)造規(guī)則同上。還原結(jié)果與上述結(jié)果完全一致。

2還原方法的確定依據(jù)?
? 二叉樹遍歷過(guò)程中,在中序序列中,根結(jié)點(diǎn)的左子樹中的所有結(jié)點(diǎn)都在根結(jié)點(diǎn)的左側(cè),根結(jié)點(diǎn)的右子樹中的所有結(jié)點(diǎn)都在根結(jié)點(diǎn)的右側(cè),這個(gè)特點(diǎn)恰好與二叉排序樹具有相同的性質(zhì);在讀入序列時(shí),前序序列則從左向右讀,這恰好與遍歷二叉樹的順序相同;后序序列從右向左讀,則按照根結(jié)點(diǎn)、右子樹、左子樹的順序還原。?
? (1)設(shè)二叉樹共有N個(gè)結(jié)點(diǎn)(N為大于1的正整數(shù)),我們按照還原方法給中序序列中的這N個(gè)結(jié)點(diǎn)分別賦予權(quán)值1,2…N,設(shè)根結(jié)點(diǎn)的權(quán)值為M(1
? (2)由二叉樹的遍歷規(guī)則可知,權(quán)值為1,2…M-1的結(jié)點(diǎn)為根結(jié)點(diǎn)的左子樹中的結(jié)點(diǎn),而權(quán)值為M+1,…N的結(jié)點(diǎn)為根結(jié)點(diǎn)的右子樹中的結(jié)點(diǎn)。?
? (3)將這N個(gè)結(jié)點(diǎn)劃分成3個(gè)子集AA=(1,2…M-1)BB=(M)CC=(M+1,…N),由于前序序列第一個(gè)讀入的結(jié)點(diǎn)必定為二叉根的根結(jié)點(diǎn),所以BB為根結(jié)點(diǎn),AA集為左子樹,CC集為右子樹。?
? (4)同理不斷讀入前序序列中的結(jié)點(diǎn),依次遞歸還原BB對(duì)應(yīng)的左子樹和CC對(duì)應(yīng)的右子樹,最后將三棵子樹合并成以BB為根結(jié)點(diǎn)、AA的根結(jié)點(diǎn)為BB的左子樹、CC的根結(jié)點(diǎn)為BB的右子樹的一棵二叉排序樹。?
? (5)同理可以得出,由中序序列和后序序還原二叉樹的規(guī)則也成立。?
? (6)在還原過(guò)程中,讀入序列的順序也遵循也先根結(jié)點(diǎn),后子樹的規(guī)律。?
? 3總結(jié)?
? 在二叉樹的一些應(yīng)用中,如平衡二叉樹、紅黑樹等,常常要觀察二叉樹的形態(tài),對(duì)其進(jìn)行判斷并調(diào)整。根據(jù)遍歷序列和二叉排序樹的性質(zhì)快速還原出二叉樹對(duì)于研究相關(guān)的問(wèn)題有很大的幫助。

?

上面可以得出前序擴(kuò)展序列 ABD/E///C//FG//H

后序?yàn)?ED##B###G##HFCA

?

void PreCreate(Node* p)

{

if(line == end)

?? return;

? if(line == “/”)

????? p = NULL;

else{

?? p = new NOde();

?? p->data = line;

?? PreCreate(p->Left);

??? PreCreate(p->Right);

}

}

本文轉(zhuǎn)自博客園知識(shí)天地的博客,原文鏈接:二叉樹的前序、中序、后序遍歷與創(chuàng)建,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原博主。

總結(jié)

以上是生活随笔為你收集整理的二叉树的前序、中序、后序遍历与创建的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。