【資料結構】二叉樹的建立與遍歷
演算法設計思路
二叉樹的建立採用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);
}
}
}
相關文章
- 資料結構——樹與二叉樹的遍歷資料結構二叉樹
- 資料結構 二叉樹遍歷資料結構二叉樹
- 資料結構-二叉樹的儲存結構與遍歷資料結構二叉樹
- 資料結構之遍歷二叉樹資料結構二叉樹
- 資料結構與演算法-二叉樹遍歷資料結構演算法二叉樹
- 二叉樹的建立與遍歷二叉樹
- 資料結構與演算法——二叉樹的前序遍歷,中序遍歷,後序遍歷資料結構演算法二叉樹
- 實戰資料結構(11)_二叉樹的遍歷資料結構二叉樹
- 二叉樹的構造與遍歷二叉樹
- python資料結構之二叉樹遍歷的實現Python資料結構二叉樹
- 【資料結構】二叉樹遍歷(遞迴+非遞迴)資料結構二叉樹遞迴
- 二叉樹的建立、前序遍歷、中序遍歷、後序遍歷二叉樹
- 【資料結構&演算法】11-樹基礎&二叉樹遍歷資料結構演算法二叉樹
- 資料結構實驗:二叉樹的遍歷(C語言版)資料結構二叉樹C語言
- 一本正經的聊資料結構(5):二叉樹的儲存結構與遍歷資料結構二叉樹
- 二叉樹的建立與遍歷(遞迴實現)二叉樹遞迴
- 中序線索二叉樹的建立與遍歷二叉樹
- Python資料結構——解析樹及樹的遍歷Python資料結構
- 二叉樹建立,前序遍歷,中序遍歷,後序遍歷 思路二叉樹
- 【資料結構與演算法】二叉樹的 Morris 遍歷(前序、中序、後序)資料結構演算法二叉樹
- 資料結構之二叉樹的建立資料結構二叉樹
- 【資料結構】建立二叉樹的方法資料結構二叉樹
- 二叉樹排序樹的建立,遍歷和刪除二叉樹排序
- 二叉樹遍歷順序與方法小結二叉樹
- 資料結構-二叉樹的遍歷(類C語言描寫敘述)資料結構二叉樹C語言
- 二叉樹遍歷方法總結二叉樹
- 二叉樹的遍歷二叉樹
- 二叉樹的建立及遍歷(JavaScript實現)二叉樹JavaScript
- 資料結構 排序二叉樹(BST) 插入刪除查詢 中序遍歷 銷燬(後序遍歷)資料結構排序二叉樹
- [資料結構]二叉樹的前中後序遍歷(遞迴+迭代實現)資料結構二叉樹遞迴
- 二叉樹---遍歷二叉樹
- 二叉樹遍歷二叉樹
- [資料結構] 根據前中後序遍歷中的兩種構造二叉樹資料結構二叉樹
- LintCode 前序遍歷和中序遍歷樹構造二叉樹二叉樹
- 建立二叉樹:層次遍歷--樹的寬度高度,後序遍歷--祖先節點二叉樹
- 遍歷結果推導二叉樹二叉樹
- SDUTOJ 2128 樹結構練習——排序二叉樹的中序遍歷排序二叉樹
- 二叉樹的建立、遍歷、廣義錶轉換二叉樹