实验三:二叉树的操作(结构转换,递归和非递归的先序、中序和后序遍历,以及层次遍历,叶子结点和总结点的计数)

(1)将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树性质5,建立二叉树的二叉链表。

(2) 写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。

(3)写出对用二叉链表存储的二叉树进行层次遍历算法。

(4)求二叉树的所有叶子及结点总数。

//Sinhaeng Hhjian
#include<stdio.h>
#include<string.h> 
#include<stdlib.h>
#define MAX 100005
typedef struct BTNode{
	char data;
	struct BTNode *lchild, *rchild;
}BTNode, *BiTree;

struct Queue{
	BiTree *base;
	int f, r;
};

void InitQueue(Queue &q){
	q.base = (BiTree *)malloc(sizeof(BiTree) * MAX);
	q.f = q.r = 0;
}

void InQueue(Queue &q, BiTree bt){
	q.base[q.r++] = bt;
}

int IsEmpty(Queue q){
	return q.f == q.r? 1:0;
}

void OutQueue(Queue &q, BiTree &bt){
	if(IsEmpty(q)) return ;
	bt = q.base[q.f++];
}
 
void CreatBiTree(BiTree &bt, char *Data, int n){
	Queue Q;
	int Qnum[MAX], f, r, i;
	BiTree p;
	if(n<1){
		bt = NULL;
		return;
	}
	bt = (BiTree)malloc(sizeof(BTNode));
	bt->data = Data[1];
	InitQueue(Q); InQueue(Q, bt);
	f = r = 0;
	Qnum[r++]=1;
	while(!IsEmpty(Q)){
		OutQueue(Q, p); i=Qnum[f++];
		if(2*i > n || Data[2*i] == '#')
			p->lchild = NULL;
		else{
			p->lchild = (BiTree)malloc(sizeof(BTNode));
			p->lchild->data = Data[2*i];
			InQueue(Q, p->lchild);
			Qnum[r++] = 2*i;
		}
		if(2*i+1 > n || Data[2*i+1] == '#')
			p->rchild = NULL;
		else{
			p->rchild = (BiTree)malloc(sizeof(BTNode));
			p->rchild->data = Data[2*i+1];
			InQueue(Q, p->rchild);
			Qnum[r++] = 2*i+1;
		}
	}
}

void PreOrderTraverse(BiTree bt){
	if(bt){
		printf("%3c", bt->data);
		PreOrderTraverse(bt->lchild);
		PreOrderTraverse(bt->rchild);
	}
}

void InOrderTraverse(BiTree bt){
	if(bt){
		InOrderTraverse(bt->lchild);
		printf("%3c", bt->data);
		InOrderTraverse(bt->rchild);
	}
}

void PostOrderTraverse(BiTree bt){
	if(bt){
		PostOrderTraverse(bt->lchild);
		PostOrderTraverse(bt->rchild);
		printf("%3c", bt->data);
	}
}

struct Stack{
	BiTree *base;
	int top;
};

void Push(Stack &s, BiTree bt){
	s.base[++s.top] = bt;
}

int GetTop(Stack s, BiTree &bt){
	if(!s.top)
		return 0;
	bt = s.base[s.top];
	return 1;
}

int IsSEmpty(Stack s){
	return s.top==0? 1 : 0;
}

void InitStack(Stack &s){
	s.base = (BiTree *)malloc(MAX*(sizeof(BiTree)));
	s.top=0;
}

void Pop(Stack &s, BiTree &bt){
	if(IsSEmpty(s))
		return ;
	bt = s.base[s.top];
	s.top--;
}

void PreOrderTraverse2(BiTree bt){
	if(bt){
		Stack S;
		BiTree p;
		InitStack(S);
		Push(S, bt);
		while(!IsSEmpty(S)){
			while(GetTop(S, p) && p){
				printf("%3c", p->data);
				Push(S, p->lchild);
			}
			Pop(S, p);
			if(!IsSEmpty(S)){
				Pop(S, p);
				Push(S, p->rchild);
			}
		}
	}
} 

void InOrderTraverse2(BiTree bt){
	if(bt){
		Stack S;
		BiTree p;
		InitStack(S);
		Push(S, bt);
		while(!IsSEmpty(S)){
			while(GetTop(S, p) && p)
				Push(S, p->lchild);
			Pop(S, p);
			if(!IsSEmpty(S)){
				Pop(S, p);
				printf("%3c", p->data);
				Push(S, p->rchild);
			}
		}
	}
} 

void PostOrderTraverse2(BiTree bt){
	if(bt){
		Stack S;
		BiTree p, q;
		InitStack(S);
		Push(S, bt);
		while(!IsSEmpty(S)){
			while(GetTop(S, p) && p)
				Push(S, p->lchild);
			Pop(S, p);
			if(!IsSEmpty(S)){
				GetTop(S, p);
				if(p->rchild)
					Push(S, p->rchild);
				else{
					Pop(S, p);
					printf("%3c", p->data);
					while(!IsSEmpty(S) && GetTop(S, q) && q->rchild == p){
						Pop(S, p);
						printf("%3c", p->data);
					}
					if(!IsSEmpty(S)){
						GetTop(S, p);
						Push(S, p->rchild);
					}
				}
			}
		}
	}
}

void LevelOrderTraverse(BiTree bt){
	if(bt){
		Queue Q;
		BiTree p;
		InitQueue(Q);
		InQueue(Q, bt);
		while(!IsEmpty(Q)){
			OutQueue(Q, p);
			printf("%3c", p->data);
			if(p->lchild)
				InQueue(Q, p->lchild);
			if(p->rchild)
				InQueue(Q, p->rchild);
		}
	}
}

void CountLeaf(BiTree bt, int &leaves, int &cnt, char *lea){
	if(bt){
		cnt++;
		CountLeaf(bt->lchild, leaves, cnt, lea);
		if(!bt->lchild && !bt->rchild)
			lea[leaves++]=bt->data;
		CountLeaf(bt->rchild, leaves, cnt, lea);
	}
}

int main(){
	BiTree bt;
	char date[MAX];
	printf("请输入一维数组结构的二叉树:\n");
	scanf("%s", date+1);
	int n=strlen(date+1);
	CreatBiTree(bt, date, n);
	printf("递归先序遍历:"); 
	PreOrderTraverse(bt);
	printf("\n");
	printf("递归中序遍历:");
	InOrderTraverse(bt);
	printf("\n");
	printf("递归后序遍历:");
	PostOrderTraverse(bt);
	printf("\n\n");
	
	printf("非递归先序遍历:"); 
	PreOrderTraverse2(bt);
	printf("\n");
	printf("非递归中序遍历:");
	InOrderTraverse2(bt);
	printf("\n");
	printf("非递归后序遍历:");
	PostOrderTraverse2(bt);
	printf("\n\n");
	
	printf("层次遍历:");
	LevelOrderTraverse(bt);
	printf("\n\n"); 
	
	int cnt=0, sum=0;
	char leaves[MAX];
	CountLeaf(bt, sum, cnt, leaves);
	printf("叶子节点总数为:%d\n", sum);
	printf("分别是:");
	for(int i=0;i<sum;i++)
		printf("%3c", leaves[i]);
	printf("\n节点总数为:%d\n", cnt); 
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hhjian6666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值