二叉樹的建立及遍歷(先序遍歷、中序遍歷、後續遍歷、層次遍歷)
阿新 • • 發佈:2019-02-19
資料結構學過有一段時間了,太長時間沒有寫程式碼,基本上都忘個差不多了,最近用到了,今天重新複習了一下,寫個二叉樹小彙總
注:我這裡節點是字元型別,所以如果節點要是儲存大於9的數字的值的話,需要將其改一下,部分功能程式碼也要隨之改變,但是隻要思想弄懂了,那麼無論改成什麼樣的資料型別,都應該是沒有問題的!
大家也可以自己寫一個試試!!!!
二叉樹的建立①:(用擴充套件先序遍歷序列建立二叉樹)
二叉樹建立②:(根據先序遍歷和中序遍歷建立二叉樹)#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef struct Node{ char data; struct Node * LChild; struct Node * RChild; }BitNode,* BiTree; void Creat(BiTree &T){ // &T 這點是一個引用,是一個指標的引用 在這裡面對指標的修改也就是對原指標的修改 char ch; cin >> ch; if(ch == '#') // 建立樹的時候輸入為 # 時說明該分支為NULL T = NULL; else{ T = new BitNode; T->data = ch; Creat(T->LChild); Creat(T->RChild); } } int main() { BiTree T; // 建立一個指向二叉樹根節點的指標 cout << "建樹 :(請輸入樹的結構(abd##e##cf###)也就是擴充套件前序遍歷)" << endl; Creat(T); cout << "二叉樹已建立好!!!!!!!!!!!!!!!!!" << endl; return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef struct Node{ char data; struct Node * LChild; struct Node * RChild; }BitNode,* BiTree; BitNode * Creat(string pre,string mid) { BiTree T = NULL; if(pre.length() > 0) { T = new BitNode; T->data = pre[0]; /* 查詢pre[0] 在中序遍歷中的位置,*/ int index = mid.find(pre[0]); /*有中序遍歷可以推出,前序遍歷中1-index個都是左子樹的, index + 1 到 pre.length 是右子樹的*/ // 前 1 - index個是左子樹,建立左子樹 T->LChild = Creat(pre.substr(1,index),mid.substr(0,index)); // 從 index 結束為右子樹,建立右子樹 T->RChild = Creat(pre.substr(index + 1),mid.substr(index + 1)); /* std::string::substr * string substr (size_t pos = 0, size_t len = npos) * pos : 開始的位置(預設為 0) * len : 偏移量,即從開始的位置數 len 長度個字元 (預設到字串的結束) */ } return T; } int main() { string pre,mid,post; // 前序遍歷 、中序遍歷、後序遍歷 cout << "根據輸入的前序和中序建樹" << endl; cout << "請輸入前序遍歷(字串,中間不要用空格之類的符號 例:4312657):"; cin >> pre; cout << endl << "請輸入中序遍歷(字串,中間不要用空格之類的符號 例:1234567):"; cin >> mid; BiTree T = Creat(pre,mid); cout << "二叉樹已建立好!!!!!!!!!!!!!!!!!" << endl; return 0; }
二叉樹建立③:(根據後序遍歷和中序遍歷建立二叉樹)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef struct Node{ char data; struct Node * LChild; struct Node * RChild; }BitNode,* BiTree; BitNode * Creat(string post,string mid) { BiTree T = NULL; if(post.length() > 0) { T = new BitNode; T->data = post[post.length() - 1]; // 查詢pre[0] 在中序遍歷中的位置, int index = mid.find(post[post.length() - 1]); /*有中序遍歷可以得到後序遍歷中1-index個都是左子樹的, index + 1 到 pre.length 是右子樹的 */ // 前 1 - index個是左子樹,建立左子樹 T->LChild = Creat(post.substr(0,index) ,mid.substr(0,index)); // 從 index 結束為右子樹,建立右子樹 T->RChild = Creat(post.substr(index ,mid.length() - 1 - index),mid.substr(index+1)); /* std::string::substr * string substr (size_t pos = 0, size_t len = npos) * pos : 開始的位置(預設為 0) * len : 偏移量,即從開始的位置數 len 長度個字元 (預設到字串的結束) */ } return T; } int main() { string pre,mid,post; // 前序遍歷 、中序遍歷、後序遍歷 cout << "根據輸入的後序和中序建樹" << endl; cout << "請輸入後序遍歷(字串,中間不要用空格之類的符號 例:2315764):"; cin >> post; cout << endl << "請輸入中序遍歷(字串,中間不要用空格之類的符號 例:1234567):"; cin >> mid; // 輸入後續和中序建立二叉樹 BiTree T = Creat(post,mid); cout << "二叉樹已建立好!!!!!!!!!!!!!!!!!" << endl; return 0; }
二叉樹的遍歷:(前、中、後 及 層次遍歷)
/*
* 在遍歷的過程中,前中後都是針對父親來說的,輸出的時候,每個節點都是作為父親節點輸出的
*/
// 前序遍歷 先父親節點先遍歷 ,即先父親,再左兒子,最後是右兒子
void preorder(BiTree T)
{
if(T)
{
cout << T->data << " ";
preorder(T->LChild);
preorder(T->RChild);
}
}
// 中序遍歷 父親節點在中間遍歷, 即先左兒子,再父親,最後是右兒子
void midorder(BiTree T)
{
if(T)
{
midorder(T->LChild);
cout << T->data << " ";
midorder(T->RChild);
}
}
// 後續遍歷 父親節點在最後遍歷, 即先左兒子,再右兒子,最後是父親
void postorder(BiTree T)
{
if(T)
{
postorder(T->LChild);
postorder(T->RChild);
cout << T->data << " ";
}
}
/*
* 層次遍歷,利用佇列進行層次遍歷,遍歷到某個節點,
* 如果該節點有左孩子,右孩子,那麼就將其孩子放入佇列中
*/
void Levelorder(BiTree T)
{
queue<BiTree>Q;
BiTree t;
Q.push(T);
while(!Q.empty())
{
t = Q.front();
Q.pop();
cout << t->data << " ";
if(t->LChild)
{
Q.push(t->LChild);
}
if(t->RChild)
{
Q.push(t->RChild);
}
}
}