二叉樹的遍歷算法(詳細(xì)示例分析)
#include<iostream>
#include<assert.h>
#include<stack>
#include<queue>
using namespace std;
struct Node
{
int v;
Node *leftChild,*rightChild;
Node():leftChild(NULL),rightChild(NULL){}
Node(int vv):leftChild(NULL),rightChild(NULL)
{
v=vv;
}
};
void print(int v)
{
cout<<v<<" ";
}
void PreOrderTraverse(Node *n, void (* visit)(int))
{
assert(n!=NULL&&visit!=NULL);
(*visit)(n->v);
if(n->leftChild!=NULL) PreOrderTraverse(n->leftChild,visit);
if(n->rightChild!=NULL) PreOrderTraverse(n->rightChild,visit);
}
void InOrderTraverse(Node *n, void (* visit)(int))
{
assert(n!=NULL&&visit!=NULL);
if(n->leftChild!=NULL) InOrderTraverse(n->leftChild,visit);
(*visit)(n->v);
if(n->rightChild!=NULL) InOrderTraverse(n->rightChild,visit);
}
void PostOrderTraverse(Node *n, void (* visit)(int))
{
assert(n!=NULL&&visit!=NULL);
if(n->leftChild!=NULL) PostOrderTraverse(n->leftChild,visit);
if(n->rightChild!=NULL) PostOrderTraverse(n->rightChild,visit);
(*visit)(n->v);
}
//非遞歸版本,將遞歸改成非遞歸一般都要利用一個棧
//每次訪問一個結(jié)點(diǎn)后,在向左子樹遍歷下去之前,利用這個棧記錄該結(jié)點(diǎn)的右子女(如果有的話)結(jié)點(diǎn)的地址,
//以便在左子樹退回時可以直接從棧頂取得右子樹的根結(jié)點(diǎn),繼續(xù)右子樹的遍歷
void PreOrder(Node *n, void (* visit)(int))
{
stack<Node*> sta;
sta.push(n);
while(!sta.empty())
{
Node * t=sta.top();
sta.pop();
assert(t!=NULL);
(*visit)(t->v);
if(t->rightChild!=NULL) sta.push(t->rightChild);
if(t->leftChild!=NULL) sta.push(t->leftChild);
}
}
//非遞歸中序遍歷
void InOrder(Node * n , void (* visit) (int))
{
stack<Node *> sta;
sta.push(n);
Node * p= n;
while(!sta.empty()&&p!=NULL)
{
p=sta.top();
while(p!=NULL&&!sta.empty())
{
sta.push(p->leftChild);
p=p->leftChild;
}
sta.pop();//彈出空指針
if(!sta.empty())
{
p=sta.top();
sta.pop();
(*visit)(p->v);
sta.push(p->rightChild);
}
}
}
//非遞歸后續(xù)遍歷
struct StkNode
{
Node * ptr;
bool tag;//false=left and true=right
StkNode():ptr(NULL),tag(false)
{}
};
void PostOrder(Node * n ,void (*visit) (int))
{
stack<StkNode> sta;
StkNode w;
Node * p = n;
do {
while(p!=NULL)
{
w.ptr=p;
w.tag=false;
sta.push(w);
p=p->leftChild;
}
bool flag=true;
while(flag&&!sta.empty())
{
w=sta.top();
sta.pop();
p=w.ptr;
if(!w.tag)//left,如果從左子樹返回,則開始遍歷右子樹
{
w.tag=true;//標(biāo)記右子樹
sta.push(w);
flag=false;
p=p->rightChild;
}
else
{
(*visit)(p->v);
}
}
} while(!sta.empty());
}
//層序遍歷,利用隊(duì)列
void LevelOrderTraverse(Node * n , void (* visit )(int))
{
assert(n!=NULL&&visit!=NULL);
queue<Node * > que;
que.push(n);
while(!que.empty())
{
Node * t=que.front();
(*visit)(t->v);
que.pop();
if(t->leftChild!=NULL) que.push(t->leftChild);
if(t->rightChild!=NULL) que.push(t->rightChild);
}
}
int main()
{
Node * head= new Node(0);
Node * node1= new Node(1);
Node * node2= new Node(2);
Node * node3= new Node(3);
Node * node4= new Node(4);
Node * node5= new Node(5);
Node * node6= new Node(6);
head->leftChild=node1;
head->rightChild=node2;
node1->leftChild=node3;
node1->rightChild=node4;
node2->rightChild=node5;
node4->leftChild=node6;
/* LevelOrderTraverse(head,print);
cout<<endl;
PreOrderTraverse(head,print);
cout<<endl;*/
InOrder(head,print);
cout<<endl;
InOrderTraverse(head,print);
cout<<endl;
PostOrder(head,print);
cout<<endl;
PostOrderTraverse(head,print);
cout<<endl;
return 0;
}
- 平衡二叉樹的實(shí)現(xiàn)實(shí)例
- 二叉樹的非遞歸后序遍歷算法實(shí)例詳解
- 二叉樹先序遍歷的非遞歸算法具體實(shí)現(xiàn)
- 二叉樹先根(先序)遍歷的改進(jìn)
- c語言版本二叉樹基本操作示例(先序 遞歸 非遞歸)
- python二叉樹遍歷的實(shí)現(xiàn)方法
- python二叉樹的實(shí)現(xiàn)實(shí)例
- C++二叉樹結(jié)構(gòu)的建立與基本操作
- 二叉樹遍歷 非遞歸 C++實(shí)現(xiàn)代碼
- 先序遍歷二叉樹的遞歸實(shí)現(xiàn)與非遞歸實(shí)現(xiàn)深入解析
- PHP Class&Object -- 解析PHP實(shí)現(xiàn)二叉樹
- PHP Class&Object -- PHP 自排序二叉樹的深入解析
- 如何在二叉樹中找出和為某一值的所有路徑
- 探討:C++實(shí)現(xiàn)鏈?zhǔn)蕉鏄?用非遞歸方式先序,中序,后序遍歷二叉樹)
- 深入理解二叉樹的非遞歸遍歷
- 深入遍歷二叉樹的各種操作詳解(非遞歸遍歷)
- 深入二叉樹兩個結(jié)點(diǎn)的最低共同父結(jié)點(diǎn)的詳解
- 平衡二叉樹AVL操作模板
相關(guān)文章
Winform學(xué)生信息管理系統(tǒng)主頁面設(shè)計(jì)(2)
這篇文章主要為大家詳細(xì)介紹了Winform學(xué)生信息管理系統(tǒng)主頁面設(shè)計(jì)思路,感興趣的小伙伴們可以參考一下2016-05-05深入淺出掌握Unity ShaderLab語法基礎(chǔ)
Unity中所有Shader文件都通過一種陳述性語言進(jìn)行描述,稱為“ShaderLab”, 這篇文章主要介紹了Unity圖形學(xué)之ShaderLab入門基礎(chǔ),需要的朋友可以參考下2023-05-05C# 中的IComparable和IComparer的使用及區(qū)別
這篇文章主要介紹了C# 中的IComparable和IComparer的使用及區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01C#中DataGridView動態(tài)添加行及添加列的方法
這篇文章主要介紹了C#中DataGridView動態(tài)添加行及添加列的方法,涉及C#中DataGridView針對行與列動態(tài)操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09