【資料結構】二叉樹的建立與遍歷
演算法設計思路
二叉樹的建立採用struct指標建立結點,每個結點內建兩個struct指標來指向它的左右孩子,其中建立方法可採用先序,中序、後序。這裡僅介紹先序建樹,中序建樹和後序建樹實際上殊途同歸。
建樹程式碼如下
void build(Btree &t)
/**
* @description: 建樹
* 採用先序建樹,先根後左右
* @param {*Btree &t}
*/
{
char s;
sc("%c", &s);
if (isdigit(s))
{
t = new btree;
t->data = s;
build(t->l);
build(t->r);
}
else
t = NULL;
}
這邊先簡單敘述一下二叉樹的先序、中序、後序遍歷的遞迴方法。首先對於先序遍歷,採用根左右的順序輸出,所以每遇到一個結點就先輸出它對應的值,再先遞迴它的左孩子然後遞迴它的右孩子。
程式碼如下
void pre_rec(Btree t)
/**
* @description: 遞迴先序遍歷二叉樹
* @param {*Btree t}
*/
{
if (t != NULL)
{
pr("%c ", t->data);
pre_rec(t->l);
pre_rec(t->r);
}
}
void in_rec(Btree t)
/**
* @description: 遞迴中序遍歷二叉樹
* @param {*Btree t}
*/
{
if (t != NULL)
{
in_rec(t->l);
pr("%c ", t->data);
in_rec(t->r);
}
}
void post_rec(Btree t)
/**
* @description: 遞迴後序遍歷二叉樹
* @param {*Btree t}
*/
{
if (t != NULL)
{
post_rec(t->l);
post_rec(t->r);
pr("%c ", t->data);
}
}
先序遍歷的非遞迴方法: 從根結點開始往左孩子方向遍歷,每遍歷到一個元素就把它對應的值輸出,然後將該結點入棧,直至左孩子為空,然後彈出棧頂結點,遍歷其右子樹,如此往復直至棧空且結點為空。
void pre_transe(Btree ti)
/**
* @description: 非遞迴先序遍歷二叉樹
* 從根結點開始往左孩子方向遍歷,每遍歷到一個元素就
* 把它對應的值輸出,然後將該結點入棧,直至左孩子為
* 空,然後彈出棧頂結點,遍歷其右子樹,如此往復直至
* 棧空且結點為空。
* @param {*Btree ti}
*/
{
stack<Btree> s;
while (ti != NULL || !s.empty())
{
while (ti != NULL)
{
pr("%c ", ti->data);
s.push(ti);
ti = ti->l;
}
if (!s.empty())
{
ti = s.top()->r;
s.pop();
}
}
}
非遞迴中序遍歷二叉樹 從根結點開始往左孩子方向遍歷,然後將該結點入棧,直至左孩子為空,然後彈出棧頂結點並輸出該結點對應的元素的值,接著遍歷其右子樹如此往復直至棧空且結點為空。
void in_transe(Btree ti)
/**
* @description: 非遞迴中序遍歷二叉樹
* 從根結點開始往左孩子方向遍歷,然後將該結點入棧,
* 直至左孩子為空,然後彈出棧頂結點並輸出該結點對
* 應的元素的值,接著遍歷其右子樹如此往復直至棧空
* 且結點為空。
* @param {*Btree ti}
*/
{
stack<Btree> s;
while (ti != NULL || !s.empty())
{
while (ti != NULL)
{
s.push(ti);
ti = ti->l;
}
if (!s.empty())
{
ti = s.top();
s.pop();
pr("%c ", ti->data);
ti = ti->r;
}
}
}
非遞迴後序遍歷二叉樹從根節點開始順序遍歷其左孩子,並將每個順序遍歷到的左孩子入棧同時標記其入棧次數,當左孩子為空 時,彈出棧頂元素,判斷棧頂元素入棧次數,若為2則輸出棧頂元素對應的值,並將棧頂結點置為空,避免陷入死迴圈,若為1,則將該節點再次入棧,並自增其入棧次數,然後遍歷其右子樹,如此往復,直至棧空且結點為空。
void post_transe(Btree ti)
/**
* @description: 非遞迴後序遍歷二叉樹
* 從根節點開始順序遍歷其左孩子,並將每個順序遍歷
* 到的左孩子入棧同時標記其入棧次數,當左孩子為空
* 時,彈出棧頂元素,判斷棧頂元素入棧次數,若為2則
* 輸出棧頂元素對應的值,並將棧頂結點置為空,避免
* 陷入死迴圈,若為1,則將該節點再次入棧,並自增其
* 入棧次數,然後遍歷其右子樹,如此往復,直至棧空
* 且結點為空。
* @param {*Btree ti}
*/
{
stack<Btree> s;
while (ti != NULL || !s.empty())
{
while (ti != NULL)
{
ti->visit = 1;
s.push(ti);
ti = ti->l;
}
if (!s.empty())
{
ti = s.top();
s.pop();
if(ti->visit == 1)
{
ti->visit++;
s.push(ti);
ti = ti->r;
}
else
{
if(ti->visit == 2)
{
pr("%c ", ti->data);
ti = NULL;
}
}
}
}
}
層序遍歷二叉樹將根節點入隊後,逐一彈出隊首元素輸出它對應的值並將隊首元素的左右孩子入隊,如此往復,直至隊空
void level_transe(Btree t)
/**
* @description: 層序遍歷二叉樹
* 將根節點入隊後,逐一彈出隊首元素輸出它對應的值
* 並將隊首元素的左右孩子入隊,如此往復,直至隊空
* @param {*Btree t}
*/
{
queue<btree> q;
if (t != NULL)
{
q.push(*t);
btree ti;
while (!q.empty())
{
ti = q.front();
q.pop();
pr("%c ", ti.data);
if (ti.l != NULL)
q.push(*ti.l);
if (ti.r != NULL)
q.push(*ti.r);
}
}
}
相關文章
- 資料結構——樹與二叉樹的遍歷資料結構二叉樹
- 資料結構 二叉樹遍歷資料結構二叉樹
- 資料結構與演算法-二叉樹遍歷資料結構演算法二叉樹
- 一本正經的聊資料結構(5):二叉樹的儲存結構與遍歷資料結構二叉樹
- 【資料結構&演算法】11-樹基礎&二叉樹遍歷資料結構演算法二叉樹
- 二叉樹的建立與遍歷(遞迴實現)二叉樹遞迴
- 中序線索二叉樹的建立與遍歷二叉樹
- 【資料結構與演算法】二叉樹的 Morris 遍歷(前序、中序、後序)資料結構演算法二叉樹
- 二叉樹排序樹的建立,遍歷和刪除二叉樹排序
- 二叉樹遍歷順序與方法小結二叉樹
- 二叉樹遍歷方法總結二叉樹
- 用python講解資料結構之樹的遍歷Python資料結構
- [資料結構]二叉樹的前中後序遍歷(遞迴+迭代實現)資料結構二叉樹遞迴
- 二叉樹的遍歷二叉樹
- [資料結構] 根據前中後序遍歷中的兩種構造二叉樹資料結構二叉樹
- Codeup《演算法筆記》9.2小節——資料結構專題(2)->二叉樹的遍歷->二叉樹演算法筆記資料結構二叉樹
- 二叉樹遍歷二叉樹
- 二叉樹---遍歷二叉樹
- 二叉樹的建立、遍歷、廣義錶轉換二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 線索二叉樹的構造和遍歷二叉樹
- 完全二叉樹的遍歷二叉樹
- Kotlin 鏈式儲存的二叉樹的建立、遍歷Kotlin二叉樹
- 玩轉二叉樹(樹的遍歷)二叉樹
- 資料結構(樹):二叉樹資料結構二叉樹
- 二叉樹建立後,如何使用遞迴和棧遍歷二叉樹?二叉樹遞迴
- 388,先序遍歷構造二叉樹二叉樹
- 【亡羊補牢】挑戰資料結構與演算法 第51期 LeetCode 102. 二叉樹的層序遍歷(二叉樹)資料結構演算法LeetCode二叉樹
- 二叉樹遍歷方法二叉樹
- 二叉樹遍歷 -- JAVA二叉樹Java
- 【圖解資料結構】 一組動畫徹底理解二叉樹三種遍歷圖解資料結構動畫二叉樹
- C++樹——遍歷二叉樹C++二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- WeetCode4 —— 二叉樹遍歷與樹型DP二叉樹
- 從中序與後序遍歷序列構造二叉樹二叉樹
- 二叉樹:構造二叉樹(通過前序和中序遍歷)、映象翻轉、層次遍歷二叉樹
- 二叉樹的按層遍歷二叉樹
- 二叉樹的遍歷實現二叉樹