二叉树的基本算法实现

二叉树的基本算法实现

实验目的:
   用二叉链表存储方式存储二叉树,并实现以下相关算法:
   1、创建二叉树
   2、用非递归算法先中后序遍历二叉树
   3、分别求出二叉树中度为012的结点个数
   4、求出树的高度
   5、销毁二叉树

实验代码如下:

#include 
#include 
#include 
using namespace std;			//输入输出cin cout必须要带

#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 100

char ch;
typedef char TElemType;
typedef int Status;

typedef struct BiTNode {
	TElemType data;
	struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

BiTNode *T;
BiTree q, p;

typedef BiTree SElemType;

typedef struct { 						//定义顺序栈
	SElemType *base;
	SElemType *top;
	int stacksize;
} SqStack;
SqStack S;

Status InitStack(SqStack &S) {
	S.base = new SElemType[MAXSIZE];
	if(!S.base) exit(OVERFLOW);
	S.top = S.base;
	S.stacksize = MAXSIZE;
	return OK;
}
Status Push(SqStack &S, SElemType e) { //入栈
	if(S.top - S.base == S.stacksize)  //判断栈满
		return ERROR;
	*S.top++ = e;                     //元素e压入栈顶,栈顶指针上移一位;
	return OK;
}
Status Pop(SqStack &S, SElemType &e) { //出栈
	if(S.top == S.base)   return ERROR;
	e = *--S.top;
	return OK;
}
SElemType GetTop(SqStack S) { 			//取栈顶元素
	if(S.top != S.base)   return *(S.top - 1);
}
Status StackEmpty(SqStack &S) {
	if(S.top - S.base == 0)    return OK;
	else return ERROR;
}

void CreatBiTree(BiTree &T) { 		//建树
	cin >> ch;						//读入字符
	if(ch == '#') T = NULL;			//如果字符为'#',说明已经到了叶结点
	else { 							//递归
		T = new BiTNode;
		T->data = ch;
		CreatBiTree(T->lchild);
		CreatBiTree(T->rchild);
	}
}

void PreOrderTraverse(BiTree T) { 	//非递归先序
	InitStack(S);					//初始化栈S
	p = T;
	while(p || !StackEmpty(S)) {	//如果树不为空或者栈不为空
		if(p) {
			Push(S, p) ;			//将结点入栈
			cout << p->data;		//输出根结点的值
			p = p->lchild ;			//把左孩子作为根节点
		} else { 					//如果树空,说明左树已经遍历完成
			Pop(S, p) ;				//弹出结点
			p = p->rchild ;			//开始遍历右树
		}
	}
}
void InOrderTraverse(BiTree T) { 	//非递归中序遍历
	InitStack(S);					//初始化栈
	p = T;
	q = new BiTNode;
	while(p || !StackEmpty(S)) {
		if(p) { 					//p非空
			Push(S, p);				//根指针进栈
			p = p->lchild;			//根指针进栈,遍历左子树
		} else { 					//p为空
			Pop(S, q);				//退栈
			cout << q->data;		//访问根结点
			p = q->rchild;			//遍历右子树
		}
	}
}
void PostOrderTraverse(BiTree T) {  //非递归后序遍历
	InitStack(S);
	Push(S, T);						//把根节点进栈
	BiTNode *pre, *cur;
	cur = NULL;						//当前结点
	pre = NULL;						//上一结点
	while(!StackEmpty(S)) { 		//栈非空
		cur = GetTop(S);			//把根节点给当前结点
		if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild))) {
			//如果左右子树都没有或者左右子树都已经访问过了
			cout << cur->data;		//直接输出根结点
			Pop(S, cur);			//将此时的根节点弹出
			pre = cur;				//更新pre
		} else { 					//记得先进右子树后进左子树,这样输出的顺序才对。
			if(cur->rchild != NULL) { //如果右子树不为空
				Push(S, cur->rchild) ;//把右子树进栈
			}
			if(cur->lchild != NULL) { //如果左子树不为空
				Push(S, cur->lchild) ;//把左子树进栈
			}
		}
	}
}

/*分别求出二叉树中度为0、1、2的结点个数*/

//二叉树的度为0的结点个数
int CountLeaf0 (BiTree T, int& count0) {
	if ( T ) {
		if (T->lchild == NULL&&T->rchild == NULL)
			count0++;     // 对叶子结点计数
		CountLeaf0( T->lchild, count0);
		CountLeaf0( T->rchild, count0);
		
	}
	return count0;
}

//二叉树的度为1的结点个数
int CountLeaf1 (BiTree T, int& count1) {
	if ( T ) {
		if ((T->lchild == NULL &&T->rchild != NULL)||(T->lchild != NULL &&T->rchild == NULL))
			count1++;     // 对叶子结点计数
		CountLeaf1( T->lchild, count1);
		CountLeaf1( T->rchild, count1);
	}
	return count1;
}

//二叉树的度为2的结点个数
int CountLeaf2 (BiTree T, int& count2) {
	if ( T ) {
		if (T->lchild != NULL&&T->rchild != NULL)
			count2++;     // 对叶子结点计数
		CountLeaf2( T->lchild, count2);
		CountLeaf2( T->rchild, count2);
	}
	return count2;
}

/*求出树的高度*/
int Depth (BiTree T) { // 返回二叉树的深度
	int depthLeft;
	int depthRight;
	int depthval;
	if ( !T )    depthval = 0;
	else   {
		depthLeft = Depth( T->lchild );
		depthRight= Depth( T->rchild );
		depthval = 1 + (depthLeft > depthRight ? depthLeft : depthRight);
	}
	return depthval;
}

/*销毁二叉链表*/
void DestroyBiTree(BiTree &T) {
	if (T) return;
	else {
		DestroyBiTree(T->lchild);
		DestroyBiTree(T->rchild);
		free(T);
	}
}

int main() {
	BiTree T;
	int num0,num1,num2;
	int height;
	int count0 = 0;
	int count1 = 0;
	int count2 = 0;
	printf("请输入二叉树,'#'为空\n");
	CreatBiTree(T);

	printf("\n非递归先序遍历\n");
	PreOrderTraverse(T);

	printf("\n非递归中序遍历\n");
	InOrderTraverse(T);

	printf("\n非递归后序遍历\n");
	PostOrderTraverse(T);

	printf("\n二叉树的度为0的结点个数:");
	num0 =  CountLeaf0(T,count0);
	printf("%d\n",num0);

	printf("\n二叉树的度为1的结点个数:");
	num1 = CountLeaf1(T,count1);
	printf("%d\n",num1);
			
	printf("\n二叉树的度为2的结点个数:");
	num2 = CountLeaf2(T,count2);
	printf("%d\n",num2);
	
	printf("\n求出树的高度:");
	height = Depth(T);
	printf("%d\n",height);

	DestroyBiTree(T);
	return 0;
}

运行结果如下:
二叉树的基本算法实现_第1张图片这里所输入的二叉树必须为扩展二叉树,把叶子节点的#补齐!

你可能感兴趣的:(二叉树的基本算法实现)