二叉树的实现

 
//#include <stdafx.h>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;

typedef char ElemType;
typedef struct BiTNode 
{
	ElemType data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
}BiTNode,*pBiTree;

/*
*  递归法创建二叉树(前序法实现)
*/
void RecursionCreateBiTree(pBiTree *bt)
{
	ElemType data;
	cout << "input:" << endl;
	cin >> data;
	if(data == '#')
	{
		*bt = NULL; //空树
	}
	else
	{
		*bt = (pBiTree)malloc(sizeof(BiTNode));
		if(*bt == NULL)
		{
			cerr << "malloc error" << endl;
			exit(0);
		}
		else
		{
			(*bt)->data = data;
			RecursionCreateBiTree(&((*bt)->lchild));
			RecursionCreateBiTree(&((*bt)->rchild));
		}
	}
	return ;
}

/*
*  非递归法创建二叉树,输入时按层次输入,虚结点输入'@',结束输入'#'
*/
void NonRecursionCreateBiTree(pBiTree *bt)
{
	cout << "input:" << endl;
	ElemType data;
	cin >> data;
	if(data == '#' || data == '@')
	{
		*bt = NULL; //空树
		return ;
	}

	/*不为空树*/
	*bt = (pBiTree)malloc(sizeof(BiTNode));//创建根结点
	if(*bt == NULL)
	{
		cerr << "malloc error" << endl;
		exit(0);
	}
	(*bt)->data = data;
	(*bt)->lchild = NULL;
	(*bt)->rchild = NULL;

	queue<BiTNode*> Q;
	Q.push(*bt);	//根结点入队
	
	bool flag = 0;  //标记新结点应插入到左子树还是右子树(0左子树,1右子树)
	BiTNode * rootNode,*newNode;
	
	cout << "input:" << endl;
	cin >> data;
	while(data != '#')//输入'#'时结束
	{   
		/*创建新结点*/
		if(data == '@')
		{
			newNode = NULL;
		}
		else
		{
			newNode = (BiTNode*)malloc(sizeof(BiTNode));
			if(!newNode)
			{
				cerr << "malloc error" << endl;
				exit(0);
			}
			newNode->data = data;
			newNode->lchild = NULL;
			newNode->rchild = NULL;

			Q.push(newNode);
		}
		
		rootNode = Q.front(); //从队列中取出一个待插入子树的根结点

		/*将新结点插入到根结点上*/
		if(flag == 0)//插入到根的左子树上
		{
			rootNode->lchild = newNode;
			flag = 1;
		}
		else //插入到根的右子树上
		{
			rootNode->rchild = newNode;
			Q.pop();//根结点插入子树完毕,从队列中清除
			flag = 0;
		}

		cout << "input:" << endl;
		cin >> data;
	}
}

/*
*  访问结点函数
*/
void FunctionVisit(BiTNode *bn)
{
	cout << bn->data ;
}

/*
* 前序递归法遍历二叉树
*/
void PreOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	if(bt)
	{
		Visit(bt);
		PreOrderTraverse(bt->lchild,Visit);
		PreOrderTraverse(bt->rchild,Visit);
	}
}

/*
* 非递归法前序遍历二叉树
*/
void NonRecPreOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	stack<BiTNode*> S;
	BiTNode * node = bt;

	while(node || !S.empty())
	{
		if(node)
		{
			Visit(node);
			S.push(node->rchild);
			node = node->lchild;
		}
		else
		{
			//Visit(S.top());
			node = S.top();
			S.pop();
		}
	}
}


/*
* 中序递归法遍历二叉树
*/
void InOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	if(bt)
	{
		InOrderTraverse(bt->lchild,Visit);
		Visit(bt);
		InOrderTraverse(bt->rchild,Visit);
	}
}

/*
* 中序非递归法遍历二叉树
*/
void NonRecInOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	stack<BiTNode*> S;
	BiTNode * node = bt;

	while(node || !S.empty())
	{
		if(node)
		{
			S.push(node);
			node = node->lchild;
		}
		else
		{
			Visit(S.top());
			node = S.top()->rchild;
			S.pop();
		}
	}
}

/*
* 后序递归法遍历二叉树
*/
void PostOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	if(bt)
	{
		PostOrderTraverse(bt->lchild,Visit);
		PostOrderTraverse(bt->rchild,Visit);
		Visit(bt);
	}
}

/*
* 非递归法后序遍历二叉树
*/
void NonRecPostOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	stack<BiTNode*> S;
	BiTNode * node = bt;
	
	vector<bool> flag(100); //记录结点的右子树是否访问过

	while(node)			//一直深入到树的最左下方
	{
		S.push(node);
		flag[S.size()] = 0;
		node = node->lchild;
	}

	while(!S.empty())
	{
		if(S.top()->rchild && flag[S.size()] == 0)//右子树存在且未访问过
		{
			flag[S.size()] = 1;	//记录结点的右子树已访问
			node = S.top()->rchild;
			while(node)         //一直深入到右子树的最左下方
			{
				S.push(node);
				flag[S.size()] = 0;
				node = node->lchild;
			}
		}
		else	//若结点无子树或右子树已访问过,则遍历该结点
		{
			Visit(S.top());
			S.pop();
		}
	}
}

/*
* 层序遍历二叉树
*/
void LevelOrderTraverse(pBiTree bt,void (*Visit)(BiTNode *bn))
{
	if (bt == NULL)
	{
		return ;
	}

	/*不为空树*/
	queue<BiTNode*> Q;

	Visit(bt);
	if (bt->lchild)
	{
		Q.push(bt->lchild); 
	}
	if (bt->rchild)
	{
		Q.push(bt->rchild);
	}
	
	BiTNode * tmpNode;
	while(!Q.empty())
	{
		tmpNode = Q.front();
		Q.pop();
		Visit(tmpNode);
		if(tmpNode->lchild)
		{
			Q.push(tmpNode->lchild);
		}
		if(tmpNode->rchild)
		{
			Q.push(tmpNode->rchild);
		}
	}
}

/*
*  计算树的叶子结点数
*/
int CountLeafNode(pBiTree bt)
{
	if(bt == NULL)
	{
		return 0;
	}
	else if(bt->lchild == NULL && bt->rchild == NULL)
	{
		return 1;
	}
	else
	{
		return CountLeafNode(bt->lchild) + CountLeafNode(bt->rchild);
	}
}


/*
* 计算二叉树的结点数
*/
int CountBiTreeNode(pBiTree bt)
{
	if(bt == NULL)
	{
		return 0;
	}
	else
	{
		return 1 + CountBiTreeNode(bt->lchild) + CountBiTreeNode(bt->rchild);
	}
}

/*
* 计算树的深度 
*/
int CountBiTreeHight(pBiTree bt)
{
	int m, n;

	if(bt == NULL)
	{
		return 0;
	}
	else
	{
		m = CountBiTreeHight(bt->lchild);
		n = CountBiTreeHight(bt->rchild);
		return (m > n) ? (m + 1): (n + 1);
	}
}

/*
* 销毁二叉树
*/
void DestoryBiTree(pBiTree bt)
{
	if(bt)
	{
		DestoryBiTree(bt->lchild);
		DestoryBiTree(bt->rchild);
		free(bt);
	}	
}


int main(int argc,char *argv[])
{
	pBiTree bt = NULL;  //bt为指向一颗二叉树的指针  	 
	/*递归法创建二叉树*/
	//RecursionCreateBiTree(&bt);  
	/*非递归法创建二叉树*/
	NonRecursionCreateBiTree(&bt);

	cout << "\nPreOrderTraverse Rst:" << endl;
	PreOrderTraverse(bt,FunctionVisit);
	
	cout << "\nNonRecPreOrderTraverse Rst:" << endl;
	NonRecPreOrderTraverse(bt,FunctionVisit);

	cout << "\nInOrderTraverse Rst:" << endl;
	InOrderTraverse(bt,FunctionVisit);
	
	cout << "\nNonRecInOrderTraverse Rst:" << endl;
	NonRecInOrderTraverse(bt,FunctionVisit);

	cout << "\nPostOrderTraverse Rst:" << endl;
	PostOrderTraverse(bt,FunctionVisit);
	
	cout << "\nNonRecPostOrderTraverse Rst:" << endl;
	NonRecPostOrderTraverse(bt,FunctionVisit);

	cout << "\nLevelOrderTraverse Rst:" << endl;
	LevelOrderTraverse(bt,FunctionVisit);
	
	cout << "\nCountLeafNode:" << endl;
	cout << CountLeafNode(bt);
	
	cout << "\nCountBiTreNode:" << endl;
	cout << CountBiTreeNode(bt);

	cout << "\nCountBiTreeHight:" << endl;
	cout << CountBiTreeHight(bt);
	DestoryBiTree(bt);
	cout << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值