<pre name="code" class="cpp"> // 參考大神所寫 http://blog.csdn.net/hackbuteer1/article/details/6583988
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
typedef struct BtNode
{
char data;
struct BtNode *lchild;
struct BtNode *rchild;
}BtNode, *Bitree;
typedef struct Node
{
Bitree p;
int degree;
}Node, *pNode;
int createBtTree( Bitree *head )
{
int ret = 0;
char ch;
cin >> ch;
if( '#' == ch )
{
*head = NULL;
return ret;
}
Bitree pNode = new BtNode;
pNode->data = ch;
pNode->lchild = NULL;
pNode->rchild = NULL;
*head = pNode;
createBtTree( &(*head)->lchild );
createBtTree( &(*head)->rchild );
return ret;
}
// 三種遞歸遍歷
void preTravel( Bitree head )
{
if( head != NULL )
{
cout << head->data << ' ';
preTravel( head->lchild );
preTravel( head->rchild );
}
return;
}
void midTravel( Bitree head )
{
if( head != NULL )
{
midTravel( head->lchild );
cout << head->data << ' ';
midTravel( head->rchild );
}
return;
}
void postTravel( Bitree head )
{
if( head != NULL )
{
postTravel( head->lchild );
postTravel( head->rchild );
cout << head->data << ' ';
}
return;
}
// 三種非遞歸遍歷
void preTravel_noRecursion( Bitree head )
{
if( NULL == head )
{
return;
}
stack< Bitree > st;
st.push( head );
while( !st.empty() )
{
Bitree p = st.top();
st.pop();
cout << p->data << ' ';
if( p->rchild != NULL )
{
st.push( p->rchild );
}
if( p->lchild != NULL )
{
st.push( p->lchild );
}
}
return;
}
void midTravel_noRecursion( Bitree head )
{
if( NULL == head )
{
return;
}
Bitree cur = head;
stack< Bitree > st;
while( cur != NULL || !st.empty() )
{
while( cur != NULL )
{
st.push( cur );
cur = cur->lchild;
}
if( !st.empty() )
{
cur = st.top();
st.pop();
cout << cur->data << ' ';
cur = cur->rchild;
}
}
return;
}
// 非遞歸後序遍歷 雙棧法
void postTravel_noRecursion( Bitree head )
{
if( NULL == head )
{
return;
}
stack< Bitree > st1;
stack< Bitree > st2;
st1.push( head );
while( !st1.empty() )
{
Bitree cur = st1.top();
st1.pop();
st2.push( cur );
if( cur->lchild != NULL )
{
st1.push( cur->lchild );
}
if( cur->rchild != NULL )
{
st1.push( cur->rchild );
}
}
while( !st2.empty() )
{
Bitree cur = st2.top();
st2.pop();
cout << cur->data << ' ';
}
return;
}
// 非遞歸後序遍歷
void postTravel_noRecursion1( Bitree head )
{
if( NULL == head )
{
return;
}
Bitree cur = head;
stack< Bitree > st;
Bitree pVisited = NULL;
while( cur != NULL || !st.empty() )
{
while( cur != NULL )
{
st.push(cur);
cur = cur->lchild;
}
Bitree p = st.top();
if( NULL == p->rchild || p->rchild == pVisited ) // 右子樹爲空或者右子樹已經被訪問過了就訪問當前節點
{
cout << p->data << ' ';
pVisited = p;
st.pop();
}
else
{
cur = p->rchild;
}
}
return;
}
void levelTravel( Bitree head ) //非遞歸層次遍歷
{
if( NULL == head )
{
return;
}
queue< Bitree > qu;
qu.push( head );
while( !qu.empty() )
{
Bitree cur = qu.front();
qu.pop();
cout << cur->data << ' ';
if( cur->lchild != NULL )
{
qu.push( cur->lchild );
}
if( cur->rchild != NULL )
{
qu.push( cur->rchild );
}
}
return;
}
// 遞歸求二叉樹深度
int depth( Bitree head )
{
if( NULL == head )
{
return 0;
}
else
{
int lDepth = depth( head->lchild );
int rDepth = depth( head->rchild );
return ( lDepth > rDepth ? lDepth : rDepth ) + 1;
}
}
void freeQueue( queue< pNode > &qu )
{
while( !qu.empty() )
{
pNode p = qu.front();
qu.pop();
delete p;
}
return;
}
// 非遞歸實現基本思想:
//受後續遍歷二叉樹思想的啓發,想到可以利用後續遍歷的方法來求二叉樹的深度,
//在每一次輸出的地方替換成算棧S的大小,遍歷結束後最大的棧S長度即是棧的深度。
// 層次遍歷求樹的高度,還可以利用樹的後序遍歷求樹的高度
int depth_noRecursion( Bitree head )
{
int height = 0;
if( NULL == head )
{
height = -1;
return height;
}
queue< pNode > qu;
pNode pNd = new Node;
if( NULL == pNd )
{
cout << "depth_noRecursion func: err -1, NULL==pNd" << endl;
//freeQueue(qu);
height = -1;
return height;
}
pNd->p = head;
pNd->degree = 1;
qu.push(pNd);
while( !qu.empty() )
{
pNode cur = qu.front();
qu.pop();
height = cur->degree;
if( cur != NULL && cur->p != NULL && cur->p->lchild != NULL )
{
pNode p1 = new Node;
if( NULL == p1 )
{
cout << "depth_noRecursion func: err -1, NULL==p1" << endl;
freeQueue(qu);
height = -1;
return height;;
}
p1->p = cur->p->lchild;
p1->degree = cur->degree + 1;
qu.push(p1);
}
if( cur != NULL && cur->p != NULL && cur->p->rchild != NULL )
{
pNode p2 = new Node;
if( NULL == p2 )
{
cout << "depth_noRecursion func: err -1, NULL==p2" << endl;
freeQueue(qu);
height = -1;
return height;;
}
p2->p = cur->p->rchild;
p2->degree = cur->degree + 1;
qu.push(p2);
}
free(cur);
}
return height;
}
// 層次遍歷求樹的高度
int depth_noRecursion1( Bitree head )
{
int height = 0;
if( NULL == head )
{
height = -1;
return height;
}
queue< Bitree > qu;
qu.push(head);
while( !qu.empty() )
{
height++;
int cnt = 0;
int size = qu.size();
while( cnt < size ) // 彈出第height層所有元素
{
Bitree tmp = qu.front();
qu.pop();
cnt++;
if( tmp->lchild != NULL )
{
qu.push( tmp->lchild );
}
if( tmp->rchild != NULL )
{
qu.push( tmp->rchild );
}
}
}
return height;
}
// 計算二叉樹節點數
int countNodes( Bitree head )
{
if( NULL == head )
{
return 0;
}
return countNodes( head->lchild ) + countNodes( head->rchild ) + 1;
}
/*
ab#d##c##對應的二叉樹:
a
/ \
b c
\
d
*/
int main()
{
int ret = 0;
Bitree head = NULL;
createBtTree( &head );
cout << "遞歸遍歷結果:" << endl;
preTravel( head );
cout << endl;
midTravel( head );
cout << endl;
postTravel( head );
cout << endl;
cout << "非遞歸遍歷結果:" << endl;
preTravel_noRecursion( head );
cout << endl;
midTravel_noRecursion( head );
cout << endl;
postTravel_noRecursion( head );
cout << endl;
postTravel_noRecursion1( head );
cout << endl;
cout << "非遞歸層次遍歷: " << endl;
levelTravel( head );
cout << endl;
cout << "遞歸二叉樹的高度: " << depth( head ) << endl;
cout << "非遞歸二叉樹的高度: " << depth_noRecursion( head ) << endl;
cout << "非遞歸二叉樹的高度: " << depth_noRecursion1( head ) << endl;
cout << "二叉樹節點數: " << countNodes( head ) << endl;
return ret;
}
/*
abd#g###ce##f##
遞歸遍歷結果:
a b d g c e f
d g b a e c f
g d b e f c a
非遞歸遍歷結果:
a b d g c e f
d g b a e c f
g d b e f c a
g d b e f c a
非遞歸層次遍歷:
a b c d e f g
遞歸二叉樹的高度: 4
非遞歸二叉樹的高度: 4
非遞歸二叉樹的高度: 4
二叉樹節點數: 7
*/
二叉樹非遞歸遍歷、層次遍歷、高度、節點數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.