二叉樹非遞歸遍歷、層次遍歷、高度、節點數

<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





*/



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章