数据结构——【二叉树】——“双亲表示法”的一些操作

大家好,说一些闲话,今天给大家分享一些二叉树双亲表示法的一些操作,代码是我可爱的学长分享给我的,感觉蛮好的,很有助于思维的锻炼,所以分享给大家。

这个部分在刚开始接触的时候我连结构体是什么都没搞懂,为什么TM有两个结构体??

后来写着写着慢慢了解了,奥,一个是树的结构体,一个是结点的结构体,哈哈...博主很菜,不许笑,哈哈哈

 

好,正片现在开始!

学长给的代码没多少注释,注释基本都是博主根据理解一点点加上去的

#include<stdlib.h> 
#include<stdio.h>
#include<malloc.h>

#define max_size 100
//查找双亲表示法的公共双亲结点

typedef struct{    //结点的结构体,有数据域和双亲域
	int data;
	int parent;
}TreeNode;

typedef struct{    //树的结构体,有结点和数量域
	TreeNode tnode[max_size];
	int count;
}Tree;

//创建树
Tree createTree(){
	int num,i,d,p;
	int a[] = {1,2,3,4,5,6,7,8,9,10};    //数据域
	int b[] = {-1,0,0,1,1,1,2,2,3,3};    //双亲域
	Tree tree;
	num = 10;
	for(i = 0;i<num;i++){    //循环创建结点
		tree.tnode[i].data = a[i];
		tree.tnode[i].parent = b[i];
	}
	tree.count = num;
	return tree;
}

/**
	思路:一个结点找双亲,找到-1即为该结点的深度,把全部结点遍历一遍能找到最大的深度了!
*/
//双亲表示法查树的深度
int treeDepth(Tree *t){
	int i,depth = 1,max = 0;
	for(i = 0;i<t->count;i++){
		TreeNode node = t->tnode[i];
		while(node.parent!=-1){
			//printf("%4d",i);
			node = t->tnode[node.parent];
			depth++;
		}
		if(depth > max){
			max = depth;
		}
		depth = 1;
	}
	return max;
}

/**
	思路:找两个节点的双亲结点进行判断,小的继续找其双亲,循环如此,直到双亲相同	
*/
//双亲表示法查找两个节点公共的父节点
int findCommonParent(int i,int j,Tree tree){	//i、j为两个节点的数组内下标
	TreeNode p,q;
	int flag = 1;
	p = tree.tnode[i];
	q = tree.tnode[i];
	while(flag){
		if(p.parent > q.parent){
			p = tree.tnode[p.parent];
		}else if(p.parent < q.parent){
			q = tree.tnode[q.parent];
		}
		else if(p.parent == q.parent){
			flag = 0;
		}
	}
	return p.parent;
}

//打印二叉树
void print(Tree tree){
	int i;
	for(i = 0;i<tree.count;i++){
		printf("%4d,%4d\n",tree.tnode[i].data,tree.tnode[i].parent);
	}
}

/**
	思路:循环查找每个结点的深度,如果深度等于输入的深度,则数据+1
*/
//查找第depth层上的节点数
int countBottomLeaves(Tree *t,int depth){
	int i,dep = 1,countLeaves = 0;
	for(i=0;i<t->count;i++){
		TreeNode node = t->tnode[i];
		while(node.parent!=-1){
			node = t->tnode[node.parent];
			dep++;
		}
		if(dep==depth){
			countLeaves++;
		}
		dep = 1;
	}
	return countLeaves;
}

//全部的叶子数
int countAllLeaves(Tree *t){
	int i,j,count = 0,temp,flag = 1;
	int a[20];
	for(i = 0;i<t->count;i++){
		temp = t->tnode[i].parent;
		printf("start check %d\n",temp);
		for(j = 0;j<count;j++){
			printf("temp us %d,a[j] is %d\n",temp,a[j]);
			if(temp == a[j]){
				flag = 0;//有重复
			}
		}
		if(flag){
			a[count++] = temp;
			printf("加入%d\n",temp);
		}
		flag = 1;
	}
	return t->count-count;
}

void main(){
	int i,dep,count,allLeaves;
	Tree tree;
	tree = createTree();
	print(tree);
	i = findCommonParent(6,7,tree);
	printf("Common parent is %d\n",i);
	dep = treeDepth(&tree);
	printf("The depth of this tree is %d\n",dep);
	count = countBottomLeaves(&tree,dep);
	printf("The bottom leaves' number of this tree is %d\n",count);
	allLeaves = countAllLeaves(&tree);
	printf("All Leaves are %d\n",allLeaves);
}

这些代码,各位聪明的小伙伴应该可以看懂的吧!

如果有哪些小问题想考验博主的话,欢迎在下方留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

狮子座的程序员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值