二叉树的二叉链表表示与实现

版权声明:转载请保留出处:blog.csdn.net/algorithm_only。邮箱:liuy0711@foxmail.com】 

前面几节讲到的结构都是一种线性的数据结构,今天要说到另外一种数据结构——树,其中二叉树最为常用。二叉树的特点是每个结点至多只有两棵子树,且二叉树有左右字子树之分,次序不能任意颠倒。

二叉树的存储结构可以用顺序存储和链式存储来存储。二叉树的顺序存储结构由一组连续的存储单元依次从上到下,从左到右存储完全二叉树的结点元素。对于一般二叉树,应将其与完全二叉树对应,然后给每个结点从1到i编上号,依次存储在大小为i-1的数组中。这种方法只适用于完全二叉树,对非完全二叉树会浪费较多空间,最坏情况一个深度为k的二叉树只有k个结点,却需要长度为2的k次方减一长度的一位数组。事实上,二叉树一般使用链式存储结构,由二叉树的定义可知,二叉树的结点由一个数据元素和分别指向其左右孩子的指针构成,即二叉树的链表结点中包含3个域,这种结点结构的二叉树存储结构称之为二叉链表。

  • 二叉链表的存储结构
typedef struct tnode {
	elemtype		data;
	struct tnode		*lchild;
	struct tnode		*rchild;
}*bitree, bitnode;
  • 创建一棵二叉树(按先序序列建立)
int create_bitree(bitree *bt)
{
	elemtype	data;

	scanf("%d", &data);
	if (0 == data) {
		*bt = NULL;
	} else {
		*bt = (bitree)malloc(sizeof(bitnode));
		if (!(*bt))
			exit(OVERFLOW);
		(*bt)->data = data;
		create_bitree(&(*bt)->lchild);
		create_bitree(&(*bt)->rchild);
	}
	return OK;
}
按先序次序输入二叉树的结点值,0表示空树。
  • 二叉树的遍历(先序、中序、后序)
void preorder(bitree bt, int (*visit)(elemtype e))
{
	if (bt) {
		visit(bt->data);
		preorder(bt->lchild, visit);
		preorder(bt->rchild, visit);
	}
}
void inorder(bitree bt, int (*visit)(elemtype e))
{
	if (bt) {
		inorder(bt->lchild, visit);
		visit(bt->data);
		inorder(bt->rchild, visit);
	}
}
void postorder(bitree bt, int (*visit)(elemtype e))
{
	if (bt) {
		postorder(bt->lchild, visit);
		postorder(bt->rchild, visit);
		visit(bt->data);
	}
}
二叉树的递归算法较简单,代码简洁清晰,但递归算法效率低,执行速度慢,在下一节将说到二叉树非递归遍历算法。
  • 求二叉树的深度
int get_tree_depth(bitree bt)
{
	int ldepth, rdepth;

	if (!bt)
		return 0;
	else if (!bt->lchild && !bt->rchild)
		return 1;
	else {
		ldepth = get_tree_depth(bt->lchild);
		rdepth = get_tree_depth(bt->rchild);

		return (ldepth > rdepth ? ldepth : rdepth) + 1;
	}
}
树的深度即树的结点中最大层次,分别递归求左右子树的深度,较大子树深度为树的深度。
  • 求叶子结点数
int get_num_of_leave(bitree bt)
{
	if (!bt)
		return 0;
	else if (!bt->lchild && !bt->rchild)
		return 1;
	else
		return (get_num_of_leave(bt->lchild) + get_num_of_leave(bt->rchild));
}
递归求左右子树的叶子数,左右子树的叶子结点之和为树的叶子结点数。
  • 释放二叉树
void free_bitree(bitree *bt)
{
	if (*bt) {
		if ((*bt)->lchild)
			free_bitree(&(*bt)->lchild);
		if ((*bt)->rchild)
			free_bitree(&(*bt)->rchild);
			free(*bt);
			*bt = NULL;
	}
}
  • 算法实现源码


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值