数据结构与算法基础——二叉树

二叉树

二叉树的性质

性质1:在二叉树的第i层上至多有 2 i − 1 2^{i-1} 2i1

性质2:深度为k的二叉树至多有 2 k − 1 2^k-1 2k1个结点

性质3:对任何一颗二叉树T,如果其叶子数为 n 0 n_0 n0,度为2的结点数为 n 2 n_2 n2,则 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1

性质4:具有n个结点的完全二叉树的深度为 [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1

性质5:略

顺序存储

满二叉树的结点层次编号,依次存放二叉树中的数据元素

特点:

1.结点间关系蕴含在其存储位置中
2.浪费空间,适用于存满二叉树和完全二叉树

遍历二叉树

DLR——先序遍历
LDR——中序遍历
LRD——后序遍历
递归算法:
时间效率:O(n)
空间效率:O(n)
非递归算法(栈)

层次遍历(队列)

复制二叉树
1.如果是空树,递归结束;
2.否则,申请新结点空间,复制根结点
	1)递归复制左子树
	2)递归复制右子树

int Copy(BiTree T, BiTree &NewT){
	if(T == NULL){
		NewT = NULL;
		return 0;
	}
	else{
		NewT = new BiTNode;
		NewT->data = T->data;
		Copy(T->lChild, NewT->lChild);
		Copy(T->rChild, NewT->rChild);
	}
}
计算二叉树的深度
1.如果是空树,则深度为0;
2.否则,递归计算左子树的深度记为m,递归计算右子树的深度记为n,二叉树的深度则为m与n的较大者加1.

int Depth( BiTree T){
	if(T == NULL) return 0;
	else{
		m = Depth(T->lChild);
		n = Depth(T->rChild);
		if( m > n) return (m + 1);
		else return (n + 1);
	}
}
计算二叉树结点总数
1.如果是空树,则结点个数为0;
2.否则,结点个数为左子树的结点个数+右子树的结点个数+1.

int NodeCount(BiTree T){
	if(T == NULL){
		return 0;
	else
		return NodeCount(T->lChild) + NodeCount(T->rChild) + 1;
}
计算二叉树叶子结点数
1.如果是空树,则叶子数结点个数为0;
2.否则,为左子树的叶子结点个数+右子树的叶子结点个数

int LeadCount(BiTree T){
	if(T == 0)
		return 0;
	if(T->lChild == NULL && T->rChild == NULL)
		return 1;
	else
		return LeadCount(T->lChild) + LeadCount(T->rChild);
}

线索二叉树

提出问题:如何寻找特定遍历序列中二叉树结点的前驱和后继?

解决方法:

1.通过遍历寻找——费时间

2.再增设前驱、后继指针域——增加了储存负担。

3.利用二叉链表中的空指针域。

利用二叉链表中的空指针域:如果某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;如果某结点的右孩子为空,则将空的右孩子指针域改为指向其后继。

这种该表指向的指针称为“线索”,加上了线索的二叉树称为线索二叉树(Threaded Binary Tree)

为区分lchild和rchild指针到底是指向孩子的指针,还是指向前驱或者后继的指针,对二叉链表中每个结点增设两个标志域ltag和rtag,并约定:

ltag = 0   lchild指向该结点的左孩子
ltag = 1   lchild指向该结点的前驱
rtag = 0   rchild指向该结点的右孩子
rtag = 1   rchild指向该结点的后继

结点的结构为:

typedef struct BiThrNode{
	int data;
	int ltag, rtag;
	struct BiThrNode *lchild, rchild;
}BiThrNode, *BiThrTree;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值