二叉树非递归遍历、层次遍历、高度、节点数

<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





*/



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