二叉树的操作

二叉树的操作
内容:
(1)采用下列方法之一建立二叉树的二叉链表:
① 输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。
② 已知二叉树的先序遍历序列和中序遍历序列,或者已知二叉树的中序遍历序列和后序遍历序列,建立二叉树的二叉链表。
③ 将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树的性质5,建立二叉树的二叉链表。例如用数组a存储的二叉树的结点如下(0单元不用):

(2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。
(3)写出对用二叉链表存储的二叉树进行层次遍历算法。
(4)求二叉树的所有叶子及结点总数。
(5)求二叉树的深度。
要求:
(1)熟练掌握二叉树的书序存储结构和二叉链表的存储结构。
(2)掌握二叉树常用的四种遍历方法:先序遍历、中序遍历、后序遍历和层次遍历。
(3)会利用二叉树的遍历思想,实现对二叉树的各种操作。

`#include<stdio.h>
#include<stdlib.h>
#define stackinitsize 100
#define stackincrement 10
#define max 100
//二叉树的类型定义
typedef struct bitnode{
	char data;
	struct bitnode *lchild,*rchild;
}bitnode,*bitree;
//栈的类型定义
typedef struct {
	bitree *base;
	int top;
	int stacksize;
}sqstack;
//队列的类型定义
typedef struct{
	bitree *base;
	int front,rear;
}cqqueue;
void initstack(sqstack &S){
	//初始化栈
	S.base=(bitree*)malloc(stackinitsize*sizeof(bitree));
	if(!S.base)
		return ;
	S.top=0;
	S.stacksize=stackinitsize;
}
int stackempty(sqstack S){
	//判空
	if(S.top==0)
		return 1;
	return 0;
}
void push(sqstack &S,bitree e){
	//入栈
	S.base[S.top++]= e;
	
}
void pop(sqstack &S,bitree &e){
	//出栈
	if(S.top==0){
		return ;
	}
	e=S.base[--S.top];
}
bitree gettop(sqstack &S,bitree &e){
	e=S.base[S.top-1];
		return S.base[S.top-1];
} 
void initqueue(cqqueue &Q){
	//建队列
	Q.base=(bitree*)malloc(max*sizeof(bitree));
	if(!Q.base)
		return;
	Q.front=Q.rear=0; 
} 
int Queueempty(cqqueue Q){
	//判空
	if(Q.rear==Q.front) 
		return 1;
	return 0;
}
void enqueue(cqqueue &Q,bitree e){
	//入队列
	if((Q.rear+1)%max==Q.front)
		return;
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%max; 
}
void dequeue(cqqueue &Q,bitree &e){
	//出队列
	if(Q.rear==Q.front)
		return;
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%max; 
}
void creatbitree(bitree &bt){
	//建立二叉链表
	char ch;
	ch=getchar();
	if(ch=='#')
		bt=NULL;
	else{
		if(!(bt=(bitnode*)malloc(sizeof(bitnode))))
			return;
		bt->data=ch;
		creatbitree(bt->lchild);
		creatbitree(bt->rchild);
	}
}
void visit(char b){
	//输出
	printf("%c ",b);
}
void preordertraversexianxu(bitree bt){
	//递归遍历算法--先序 
	if(bt){
		visit(bt->data);
		preordertraversexianxu(bt->lchild);
		preordertraversexianxu(bt->rchild);
	}
}
void preordertraversezhongxu(bitree bt){
	//递归遍历算法——中序 
	if(bt){
		preordertraversezhongxu(bt->lchild);
		visit(bt->data);
		preordertraversezhongxu(bt->rchild);
	}
}
void preordertraversehouxu(bitree bt){
	//递归遍历算法——后序 
	if(bt){
		preordertraversehouxu(bt->lchild);
		preordertraversehouxu(bt->rchild);
		visit(bt->data);
	}
}


void traversexianxu(bitree bt){
	//先序遍历
	bitree p;
	if(bt){
		sqstack S;
		initstack(S);
		push(S,bt);
		while(!stackempty(S)){
			while(gettop(S,p) && p){
				visit(p->data);
				push(S,p->lchild);
			}
			pop(S,p);
			if(!stackempty(S)){
				pop(S,p);
				push(S,p->rchild);
			}
		}
	}
}

void traversezhongxu(bitree bt){
	//中序遍历
	if(bt){
		sqstack S;
		initstack(S);
		bitree p;
		push(S,bt);
		while(!stackempty(S)){
			while(gettop(S,p) && p){
				push(S,p->lchild);
			}
			pop(S,p);
			if(!stackempty(S)){
				pop(S,p);
				visit(p->data);
				push(S,p->rchild);
			}
		}
	}
}
void traversehouxu(bitree bt){
	//后序遍历
	if(bt){
		sqstack S;
		bitree p;
		bitree q;
		initstack(S);
		push(S,bt);
		while(!stackempty(S)){
			while(gettop(S,p) && p)
				push(S,p->lchild);
			pop(S,p);
			if(!stackempty(S)){
				gettop(S,p);
				if(p->rchild)
					push(S,p->rchild);
				else{
					pop(S,p);
					visit(p->data);
					while(!stackempty(S) && gettop(S,q) && q->rchild==p){
						pop(S,p);
						visit(p->data);
					}
					if(!stackempty(S)){
						gettop(S,p);
						push(S,p->rchild);
					}
			}
		}
	}
}
}

void levetraverse(bitree bt){
	//二叉链表存储的层次遍历
	if(bt){
		bitree p;
		cqqueue Q;
		initqueue(Q);
		enqueue(Q,bt);
		while(!Queueempty(Q)){
			dequeue(Q,p);
			visit(p->data);
			if(p->lchild) enqueue(Q,p->lchild);
			if(p->rchild) enqueue(Q,p->rchild);
		}
	}
}

void countleaf(bitree bt,int &leaves){
	//求叶子节点总数
	if(bt){
		countleaf(bt->lchild,leaves);
		if(!bt->lchild && !bt->rchild)
			leaves++;
		countleaf(bt->rchild,leaves);
	}
}
int Count(bitree bt)
{
	//求二叉树的节点总数 
    if(bt==NULL)
        return 0;     //空二叉树结点数为0 
    else              //左右子树结点总数加1
        return Count(bt->lchild)+Count(bt->rchild)+1;
}
int bitreedepth(bitree bt){
	//bt的深度
	int depthl,depthr;
	if(bt==NULL)//与if(bt)有何区别??
		return 0;
	else{
		depthl=bitreedepth(bt->lchild);
		depthr=bitreedepth(bt->rchild);
		if(depthl>=depthr)
			return depthl+1;
		else
			return depthr+1;
	}
}
int main()
{
	int leaf=0,depth;
	bitree bt; //为什么要用*bt??
	creatbitree(bt);
	printf("递归遍历的结果-先序:"); 
	preordertraversexianxu(bt);//递归遍历 
	printf("\n递归遍历的结果-中序:"); 
	preordertraversezhongxu(bt);//递归遍历 
	printf("\n递归遍历的结果-后序:"); 
	preordertraversehouxu(bt);//递归遍历 
	printf("\n非递归先序遍历结果:");
	traversexianxu(bt);//先序遍历
	printf("\n非递归中序遍历结果:");
	traversezhongxu(bt);//中序遍历
	printf("\n非递归后序遍历结果:");
	traversehouxu(bt);//后序遍历
	printf("\n层次遍历结果:");
	levetraverse(bt);//层次遍历 
	countleaf(bt,leaf);//叶子节点总数
	printf("\n叶子节点总数 %d\n",leaf);
	printf("二叉树的节点总数:%d\n",Count(bt));
	depth=bitreedepth(bt);//bt的深度
	printf("二叉树的深度 %d\n",depth);
	
}`
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值