樹形結構是一類重要的非線性資料結構,其中以樹和二叉樹最為常用。
二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作「左子樹」(left subtree)和「右子樹」(right subtree)。二叉樹常被用作二叉查詢樹和二叉堆或是二叉排序樹。二叉樹的每個結點至多只有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2的 i -1次方個結點;深度為k的二叉樹至多有2^(k) -1個結點;對任何一棵二叉樹t,如果其終端結點數(即葉子結點數)為n0,度為2的結點數為n2,則n0 = n2 + 1。
二叉樹的鏈式儲存結構是一類重要的資料結構,其形式定義如下:
[cpp]view plain
copy
//二叉樹結點
typedef
struct
bitnodebitnode,*bitree;
二叉樹的建立:
通過讀入乙個字串,建立二叉樹的演算法如下:
[cpp]view plain
copy
//按先序序列建立二叉樹
intcreatebitree(bitree &t)
else
return
0;
}
二叉樹的遍歷:
遍歷是對樹的一種最基本的運算,所謂遍歷二叉樹,就是按一定的規則和順序走遍二叉樹的所有結點,使每乙個結點都被訪問一次,而且只被訪問一次。由於二叉樹是非線性結構,因此,樹的遍歷實質上是將二叉樹的各個結點轉換成為乙個線性序列來表示。
遞迴演算法:
[cpp]view plain
copy
//輸出
void
visit(bitree t)
} //先序遍歷
void
preorder(bitree t)
} //中序遍歷
void
inorder(bitree t)
} //後序遍歷
void
postorder(bitree t)
}
非遞迴演算法:
<1>先序遍歷:
【思路】:訪問t->data後,將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,再先序遍歷t的右子樹。
[cpp]view plain
copy
/* 先序遍歷(非遞迴)
思路:訪問t->data後,將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,再先序遍歷t的右子樹。
*/void
preorder2(bitree t)
else
}//while
}
<2>中序遍歷
【思路】:t是要遍歷樹的根指標,中序遍歷要求在遍歷完左子樹後,訪問根,再遍歷右子樹。
先將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,訪問t->data,再中序遍歷t的右子樹。
[cpp]view plain
copy
void
inorder2(bitree t)
else
}//while
}
<3>後序遍歷
【思路】:t是要遍歷樹的根指標,後序遍歷要求在遍歷完左右子樹後,再訪問根。需要判斷根結點的左右子樹是否均遍歷過。
[cpp]view plain
copy
//後序遍歷(非遞迴)
typedef
struct
bitnodepostbitnodepost,*bitreepost;
void
postorder2(bitree t)
//左右子樹訪問完畢訪問根節點
while
(!stack.empty() && (stack.top())->tag ==
'r')
//遍歷右子樹
if(!stack.empty())
}//while
}
<4>層次遍歷
【思路】:按從頂向下,從左至右的順序來逐層訪問每個節點,層次遍歷的過程中需要用佇列。
[cpp]view plain
copy
//層次遍歷
void
levelorder(bitree t)
//右子樹不空,將右子樹入隊
if(p->rchild != null)
} }
測試用例:
輸入:abc##de#g##f###
輸出:
**:[cpp]view plain
copy
#include
#include
#include
using
namespace
std;
//二叉樹結點
typedef
struct
bitnodebitnode,*bitree;
//按先序序列建立二叉樹
intcreatebitree(bitree &t)
else
return
0;
} //輸出
void
visit(bitree t)
} //先序遍歷
void
preorder(bitree t)
} //中序遍歷
void
inorder(bitree t)
}
//後序遍歷
void
postorder(bitree t)
} /* 先序遍歷(非遞迴)
思路:訪問t->data後,將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,再先序遍歷t的右子樹。
*/void
preorder2(bitree t)
else
}//while
} /* 中序遍歷(非遞迴)
思路:t是要遍歷樹的根指標,中序遍歷要求在遍歷完左子樹後,訪問根,再遍歷右子樹。
先將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,訪問t->data,再中序遍歷t的右子樹。
*/void
inorder2(bitree t)
else
}//while
} //後序遍歷(非遞迴)
typedef
struct
bitnodepostbitnodepost,*bitreepost;
void
postorder2(bitree t)
//左右子樹訪問完畢訪問根節點
while
(!stack.empty() && (stack.top())->tag ==
'r')
//遍歷右子樹
if(!stack.empty())
}//while
} //層次遍歷
void
levelorder(bitree t)
//右子樹不空,將右子樹入隊
if(p->rchild != null)
} }
intmain()
二叉樹遍歷(前序,中序,後序
二叉樹的遍歷有三種方式,如下 1 前序遍歷 dlr 首先訪問根結點,然後遍歷左子樹,最後遍歷右子樹。簡記根 左 右。2 中序遍歷 ldr 首先遍歷左子樹,然後訪問根結點,最後遍歷右子樹。簡記左 根 右。3 後序遍歷 lrd 首先遍歷左子樹,然後遍歷右子樹,最後訪問根結點。簡記左 右 根。例1 如上圖...
二叉樹的遍歷 前序 中序 後序
include includetypedef struct bintree treenode,b tree b tree root null 函式的宣告 b tree creat tree int n void print1 void preorder b tree pointer 前序遍歷 voi...
二叉樹的前序 中序 後序遍歷
問題描述 給出一棵二叉樹返回其節點值得前序遍歷 解題思路 寫乙個遞迴函式,將每一次遍歷的節點放在vector裡,前序中序後序遍歷完成後,將vector裡的值輸出即可 實現 class solution void first vector vec,treenode root class solutio...