c++二叉樹的幾種遍歷算法
更新時(shí)間:2013年02月19日 11:52:31 作者:
c++二叉樹的幾種遍歷算法,需要的朋友可以參考一下
1. 前序/中序/后序遍歷(遞歸實(shí)現(xiàn))
復(fù)制代碼 代碼如下:
// 前序遍歷
void BT_PreOrder(BiTreePtr pNode){
if (!pNode) return;
visit(pNode);
BT_PreOrder(pNode->left);
BT_PreOrder(pNode->right); }
// 中序遍歷
void BT_PreOrder(BiTreePtr pNode){
if (!pNode) return;
BT_PreOrder(pNode->left);
visit(pNode);
BT_PreOrder(pNode->right);}
// 后序遍歷void BT_PreOrder(BiTreePtr pNode){
if (!pNode) return;
BT_PreOrder(pNode->left);
BT_PreOrder(pNode->right);
visit(pNode);}
2. 前序遍歷(非遞歸實(shí)現(xiàn))
復(fù)制代碼 代碼如下:
// 用棧實(shí)現(xiàn)
void BT_PreOrderNoRec1(BiTreePtr pNode){
stack<BiTreePtr> s;
while (!pNode || !s.empty())
{
if (!pNode)
{
visit(pNode);
s.push(pNode);
pNode = pNode->left;
}
else
{
pNode = s.pop();
pNode = pNode->right;
}
}
}
// 用棧實(shí)現(xiàn)
void BT_PreOrderNoRec2(BiTreePtr pNode){
if (!pNode)
{
stack<BiTreePtr> s;
s.push(pNode);
while (!s.empty())
{
BiTreePtr pvNode = s.pop();
visit(pvNode);
s.push(pvNode->right);
s.push(pvNode->left);
}
}}
//
不用棧實(shí)現(xiàn) 每個(gè)節(jié)點(diǎn)含父節(jié)點(diǎn)指針和isVisited【默認(rèn)為false】狀態(tài)變量 且該二叉樹含一個(gè)頭節(jié)點(diǎn)
void BT_PreOrderNoRec3(BiTreePtr pNode){
while (!pNode)
// 回溯到指向根節(jié)點(diǎn)的頭節(jié)點(diǎn)時(shí)退出
{
if( !pNode->bVisited )
// 判定是否已被訪問
{
visit(pNode);
pNode->isVisited = true;
}
if ( pNode->left && !pNode->left->isVisited )
pNode = pNode->left;
else if( pNode->right && !pNode->right->isVisited )
pNode = pNode->right;
else
//回溯
pNode = pNode->parent;
}}
3. 中序遍歷(非遞歸實(shí)現(xiàn))
復(fù)制代碼 代碼如下:
// 用棧實(shí)現(xiàn)
void BT_InOrderNoRec1(BiTreePtr pNode){
stack<BiTreePtr> s;
while (!pNode || !s.empty())
{
if (!pNode)
{
s.push(pNode);
pNode = pNode->left;
}
else
{
pNode = s.pop();
visit(pNode);
pNode = pNode->right;
}
}}
// 不用棧實(shí)現(xiàn) 每個(gè)節(jié)點(diǎn)含父節(jié)點(diǎn)指針和isVisited【默認(rèn)為false】的狀態(tài)變量 且該二叉樹含一個(gè)頭節(jié)點(diǎn)
void BT_InOrderNoRec2(BiTreePtr pNode){
while (!pNode)
// 回溯到指向根節(jié)點(diǎn)的頭節(jié)點(diǎn)時(shí)退出
{
while (pNode->left && !pNode->left->isVisited)
pNode = pNode->left;
if (!pNode->isVisited)
{
visit(pNode);
pNode->isVisited=true;
}
if (pNode->right && !pNode->right->isVisited)
pNode = pNode->right;
else
pNode = pNode->parent;
}}
4. 后序遍歷(非遞歸實(shí)現(xiàn))
復(fù)制代碼 代碼如下:
void BT_PostOrderNoRec(BiTreePtr pNode){
if(!pNode) return;
stack<BiTreePtr> s;
s.push(pNode);
while (!s.empty())
{
BiTreePtr pvNode = s.pop();
if (pvNode->isPushed)
// 表示其左右子樹都已入棧,訪問該節(jié)點(diǎn)
visit(pvNode);
else
{
if (pvNode->right)
{
pvNode->right->isPushed = false;
S.push(pvNode->right);
}
if (pvNode->left)
{
pvNode->left->isPushed = false;
s.push(pvNode->left);
}
pvNode->isPushed = true;
s.push(pvNode);
}
}}
5. 層序遍歷(使用隊(duì)列)
復(fù)制代碼 代碼如下:
void BT_LevelOrder(BiTreePtr pNode){
if (!pNode) return;
queue<BiTreePtr> q;
q.push(pNode);
BiTreePtr pvNode;
while (!q.empty())
{
pvNode = q.pop();
visit(pvNode);
if (pvNode->left)
q.push(pvNode->left);
if (pvNode->right)
q.push(pvNode->right);
}}
相關(guān)文章
C++類和對象深入探索之分文件編寫點(diǎn)和圓的關(guān)系詳解
先前把C++類和對象的封裝講完了,并且留下了一個(gè)判斷兩個(gè)立方體是否相等的案例,但是那么多知識(shí)點(diǎn),僅僅一個(gè)案例是不夠的,所以再來一個(gè)分文件編寫點(diǎn)圓關(guān)系的案例;創(chuàng)建圓類和點(diǎn)類,圓類包含點(diǎn)類,算是一個(gè)嵌套吧,順便復(fù)習(xí)一下分文件編寫的方法,開整2022-05-05詳解C語言的exp()函數(shù)和ldexp()函數(shù)以及frexp()函數(shù)
這篇文章主要介紹了詳解C語言的exp()函數(shù)和ldexp()函數(shù)以及frexp()函數(shù),注意這三個(gè)函數(shù)雖然看起來相似但實(shí)際功能卻大相徑庭!需要的朋友可以參考下2015-08-08快來領(lǐng)取!你想要的C++/C語言優(yōu)秀書籍
如何選擇合適的C++/C語言書籍,是不是已經(jīng)眼花繚亂,不知道該選擇哪本好了呢?今天我來為大家分享兩本不可錯(cuò)過的優(yōu)秀書籍2017-09-09C語言編程數(shù)據(jù)結(jié)構(gòu)棧與隊(duì)列的全面講解示例教程
本文介紹著重介紹數(shù)據(jù)結(jié)構(gòu)-棧和隊(duì)列的知識(shí),由于本文也設(shè)計(jì)多個(gè)動(dòng)態(tài)內(nèi)存開辟函數(shù),小伙伴們在學(xué)習(xí)本文之前,一定一定一定要把動(dòng)態(tài)內(nèi)存開辟相關(guān)知識(shí)掌握牢固,這樣學(xué)習(xí)起本文才能事半功倍2021-10-10