数据结构(C语言)之——顺序二叉树

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

typedef char ElemType; //节点元素的类型

typedef struct {
	ElemType elem; //节点元素数据
	bool isFull; //结点是否为满,true为满,false为空
}SqTreeNode;

typedef struct {
	SqTreeNode* elems; //存放元素数据
	int length; //二叉树的当前结点个数
	int maxSize; //该二叉树能存放的最大结点个数
}SqTree;

//创建最大结点数为maxSize的空二叉树
SqTree* createBiTree(int maxSize){
	SqTree* t = (SqTree*)malloc(sizeof(SqTree));
	t->maxSize = maxSize;
	t->length = 0;
	t->elems = (SqTreeNode*)malloc(sizeof(SqTreeNode)*maxSize);
	for(int i=0; i<maxSize; i++){
		t->elems[i].isFull = false;
	}

	printf("输入二叉树的层序遍历序列(空结点用'#'表示,如abcdfg##e###h##):\n");
	char* chars = (char*)malloc(sizeof(char)*(maxSize+1));
	scanf("%s",chars);
	for(int i=0; i<strlen(chars); i++){
		if(chars[i] != '#'){
			t->elems[i].elem = chars[i];
			t->elems[i].isFull = true;
			t->length += 1;
		}
	}
	free(chars);
	return t;
}

//释放二叉树的资源
void releaseBiTree(SqTree* t){
	free(t->elems);
	free(t);
}

//层序遍历
void floorTravel(SqTree* t){
	for(int i=0; i<t->maxSize; i++){
		if(t->elems[i].isFull == true){
			printf("%c", t->elems[i].elem);
		}
	}
}

//先序遍历
//打印结点信息
void visit(SqTreeNode node){
	printf("%c",node.elem);
}
void preOrderLoop(SqTree* t, int index){
	if(index < t->maxSize && t->elems[index].isFull == true){
		visit(t->elems[index]);
		preOrderLoop(t, index*2+1);
		preOrderLoop(t, index*2+2);
	}
}
void preOrder(SqTree* t){
	preOrderLoop(t, 0);
}

//中序遍历
void inOrderLoop(SqTree* t, int index){
	if(index < t->maxSize && t->elems[index].isFull == true){
		inOrderLoop(t, index*2+1);
		visit(t->elems[index]);
		inOrderLoop(t, index*2+2);
	}
}
void inOrder(SqTree* t){
	inOrderLoop(t, 0);
}

//后序遍历
void postOrderLoop(SqTree* t, int index){
	if(index < t->maxSize && t->elems[index].isFull == true){
		postOrderLoop(t, index*2+1);
		postOrderLoop(t, index*2+2);
		visit(t->elems[index]);
	}
}
void postOrder(SqTree* t){
	postOrderLoop(t, 0);
}

//求结点个数
int length(SqTree* t){
	return t->length;
}

//求叶子结点个数
int lengthLeaf(SqTree* t){
	int count = 0;
	for(int i=0; i<t->maxSize; i++){
		if(t->elems[i].isFull == true && 
			(i*2+1 >= t->maxSize || t->elems[i*2+1].isFull == false) && 
			(i*2+2 >= t->maxSize || t->elems[i*2+2].isFull == false)){
			count += 1;
		}
	}
	return count;
}

//求二叉树的度为1的结点个数
int lengthDegree1(SqTree* t){
	int count = 0;
	for(int i=0; i<t->maxSize; i++){
		if(t->elems[i].isFull == true && (
			(((i*2+1)<t->maxSize && t->elems[i*2+1].isFull == true) && ((i*2+2) >= t->maxSize || t->elems[i*2+2].isFull == false)) ||
			(((i*2+2)<t->maxSize && t->elems[i*2+2].isFull == true) && ((i*2+1) >= t->maxSize || t->elems[i*2+1].isFull == false)))){
			count += 1;
		}
	}
	return count;
}

//求二叉树的深度
int depth(SqTree* t){
	int index = -1;
	for(int i=t->maxSize-1; i>=0; i--){
		if(t->elems[i].isFull == true){
			index = i;
			break;
		}
	}
	index ++;
	int depth = -1;
	do{
		depth ++;
	}while(index >= pow(2.0,depth*1.0));
	return depth;
}

//输出二叉树中从每个叶子结点到根结点的路径
void printLeafPath(SqTree* t){
	//先判断是否是叶子结点
	for(int i=0; i<t->maxSize; i++){
		if(t->elems[i].isFull == true && 
			(i*2+1 >= t->maxSize || t->elems[i*2+1].isFull == false) && 
			(i*2+2 >= t->maxSize || t->elems[i*2+2].isFull == false)){
				//打印这个结点的路径
				int index = i+1;
				printf("%c: ",t->elems[i].elem);
				while(index != 0){
					visit(t->elems[index-1]);
					index /= 2;
				}
				printf("\n");
		}
	}
}

int main(){
	//创建一个二叉树(层序遍历)
	SqTree* t = createBiTree(100);

	//层序遍历
	printf("层序遍历:"); floorTravel(t); printf("\n");
	
	//前序遍历
	printf("前序遍历:"); preOrder(t); printf("\n");
	
	//中序遍历
	printf("中序遍历:"); inOrder(t); printf("\n");
	
	//后序遍历
	printf("后序遍历:"); postOrder(t); printf("\n");

	//二叉树的深度
	printf("二叉树的深度:%d\n", depth(t)); 

	//二叉树的结点个数
	printf("二叉树的结点个数:%d\n", length(t));

	//二叉树的叶子结点个数
	printf("二叉树的叶子结点个数:%d\n", lengthLeaf(t));

	//二叉树的度为1的结点个数
	printf("二叉树的度为1的结点个数:%d\n",lengthDegree1(t));

	//输出二叉树中从每个叶子结点到根结点的路径
	printf("输出二叉树中从每个叶子结点到根结点的路径:\n"); printLeafPath(t);

	releaseBiTree(t);

	return 0;
}

结果:

输入二叉树的层序遍历序列(空结点用'#'表示,如abcdfg##e###h##):
abcdfg##e###h##
层序遍历:abcdfgeh
前序遍历:abdefcgh
中序遍历:debfaghc
后序遍历:edfbhgca
二叉树的深度:4
二叉树的结点个数:8
二叉树的叶子结点个数:3
二叉树的度为1的结点个数:3
输出二叉树中从每个叶子结点到根结点的路径:
f: fba
e: edba
h: hgca

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值