二叉樹的前序、中序、后序遍歷與創建

#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;
// 前序擴展序列建立二叉樹??
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;
???????? }
???? }
}
// 壓棧的參數類型,包括局部變量和行號??
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

image

?

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

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

?

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

image

后序為 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);

}

}

本文轉自博客園知識天地的博客,原文鏈接:二叉樹的前序、中序、后序遍歷與創建,如需轉載請自行聯系原博主。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279008.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279008.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279008.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

flex-2

1、 2、 justify&#xff1a;整理版面 3、 4、歸納 justify-content&#xff1a;flex-start&#xff08;默認&#xff09;、center、flex-end 下面還會提到剩下的兩種項目在主軸上對齊方式&#xff1a; space-between:兩端對齊&#xff08;項目間距離相等&#xff09; space-ar…

TextInput

TextInput /** TextInput 是一個允許用戶在應用中通過鍵盤輸入文本的基本組件* 本組件的屬性提供了多種特性的配置,如自動完成,自動大小寫,占位文字,鍵盤類型等* 常用:* placeholder 占位符* value 輸入框的值* password 是否密文輸入* editable 是否可編輯* retureKeyType …

如何使用oracle查詢,oracle 表查詢

Oracle 的 oracle 表查詢通過scott用戶下的表來演示如何使用select語句&#xff0c;接下來對emp、dept、salgrade表結構進行解說。emp 雇員表字段名稱 數據類型 是否為空 備注-------- ----------- -------- --------EMPNO NUMBER(4) 員工編…

火狐標簽在中間_在Firefox中保留未使用的標簽

火狐標簽在中間If you have a lot of content heavy webpages open in Firefox, it soon adds up on memory usage. The BarTab extension puts unused tabs on hold and keeps them unloaded until you are ready to access them. 如果您在Firefox中打開了大量內容繁重的網頁&…

[CQOI2012]模擬工廠 題解(搜索+貪心)

[CQOI2012]模擬工廠 題解(搜索貪心) 標簽&#xff1a;題解 閱讀體驗&#xff1a;https://zybuluo.com/Junlier/note/1327574 鏈接題目地址&#xff1a;洛谷P3161 BZOJ P2667 這個題練一練綜合思想還是不錯的。。。&#xff08;然而蒟蒻不會啊&#xff09; 做法 肯定是在能完成某…

上傳文件的input問題以及FormData特性

1.input中除了type"file"還要加上name"file"&#xff0c;否則$_FILES為空&#xff0c;input的name值就是為了區分每一個input的 2.var formdata new FormData($("#form")[0]); 或者var formdata new FormData(document.getElementById("f…

iphone手機備忘錄遷移_如何在iPhone和iPad上使用語音備忘錄

iphone手機備忘錄遷移Whether you’re recording a voice message as a reminder of that million dollar idea or catching a snippet of a new song you know you’ll forget, the iPhone and iPad’s Voice Memos app is the perfect tool. 無論您是錄制語音消息來提醒這一百…

php 執行文件tar打包,利用tar for windows對大量文件進行快速打包

近期將某些網站換服務器&#xff0c;由于網站數量巨大&#xff0c;加上附件和靜態頁&#xff0c;文件數量異常多&#xff0c;考慮先打包然后直接傳過去。起初嘗試用winrar打包&#xff0c;但是發現即使選擇”僅儲存”速度仍然慢到無法接受&#xff0c;后來想到了tar&#xff0c…

DDD~領域事件中使用分布式事務

對于一個聚合來說&#xff0c;它可能會被附加很多事件&#xff0c;這里我們叫它領域事務&#xff0c;因為一個聚會我們可以把它理解成一個領域&#xff0c;一個業務。對于領域事件不清楚的同學可以看看我的這篇文章《DDD~領域事件與事件總線》&#xff0c;里面有詳細的說明&…

如何在PowerPoint中制作打字機或命令行動畫

Adding quirky animations to your Microsoft PowerPoint presentation gives your slideshow a little extra life. Not only will adding a typewriter or command line animation entertain your audience, but it will also keep them focused on the text. 在您的Microsof…

oracle中spool卸數,數據卸載--spool的使用

&#xfeff;&#xfeff;引言在項目中&#xff0c;我們經常會遇到數據的卸載、裝載需求。卸載就是需要將數據從數據庫中導入到文本文件中的需求&#xff0c;這樣的方法有很多&#xff0c;比較常用的就是spool命令。裝載就是需要將數據從文本文件中導入到數據庫中。方法也有很多…

Objective-C中的@property

1.property是什么 Property是聲明屬性的語法&#xff0c;它可以快速方便的為實例變量創建存取器&#xff0c;并允許我們通過點語法使用存取器。 存取器&#xff08;accessor&#xff09;&#xff1a;指用于獲取和設置實例變量的方法。用于獲取實例變量值的存取器是getter&#…

Linux基礎命令---findfs

findfs 查找指定卷標或者UUID的文件系統對應的設備文件。findfs將搜索系統中的磁盤&#xff0c;尋找具有標簽匹配標簽或與UUID相等的文件系統。如果找到文件系統&#xff0c;文件系統的設備名稱將打印在stdout上。 此命令的適用范圍&#xff1a;RedHat、RHEL、Ubuntu、CentOS、…

canvas 平滑運動_什么是電視上的運動平滑?人們為什么討厭它?

canvas 平滑運動Willy Barton/Shutterstock.com威利巴頓/Shutterstock.comIf you’ve just bought a new TV, you might be wondering why everything you watch feels eerily sped up and smooth, like you’re watching a live broadcast all the time. You’re not imaginin…

linux guard什么進程,使用linux系統性能監控工具KSysguard監控遠端主機介紹

KDE System Guard默認的窗口前端圖形界面使用傳感器(sensors)獲得要顯示的信息。傳感器返回的可以是一個簡單的數值或更復雜的信息如表格。針對不同的信息類型都提供了一個或多個顯示界面。這些顯示界面被組織在多個工作表中&#xff0c;工作表可以獨立存儲和加載。KSysguard主…

macbook充電_如何判斷MacBook是否正在充電

macbook充電2p2play / Shutterstock2p2play / ShutterstockForgetting to charge your MacBook properly overnight can leave you with a headache in the morning. And if you’re troubleshooting a broken MacBook, checking if it’s able to charge is one way to rule o…

mysql記錄

當沒有用EXISTS引入子查詢時&#xff0c;在選擇列表中只能指定一個表達式轉載于:https://www.cnblogs.com/niuben/p/9920741.html

PIL.Image convert to numpy array

當使用PIL.Image讀取圖像時&#xff0c;如果直接使用numpy.array()轉換會出現錯誤&#xff1a; lst list() for file_name in os.listdir(dir_image):image PIL.Image.open(file_name)lst.append(image) arr numpy.array(lst) 此時&#xff0c;上述最后一行在執行時會出現錯…

NFC服務器在Linux,linux 安裝 libnfc ,打開串口PN532

硬件準備&#xff1a;USB轉串口4針杜邦線PN532模塊IC卡一張(比如門禁卡&#xff0c;飯卡等)軟件準備&#xff1a;Ubuntu 物理機一臺能夠訪問互聯網1&#xff0c;將PN532與USB轉串口連接好,放一張IC卡靠近PN532模塊2&#xff0c;安裝libnfc&#xff1a;chunliubuntu:~$ sudo apt…

chrome同步_如何在Chrome中打開或關閉同步

chrome同步Google Chrome lets you sync up your Google account to your browser across any device. When enabled, bookmarks, history, passwords, extensions, and themes—among many other settings—sync from your Google account, creating a seamless experience no…