树与二叉树的应用

树与二叉树的应用

1.二叉排序树的应用

1.1、定义

二叉排序树(也称二叉查找树)或者是一颗空树,或者是一颗具有下列特性的非空二叉树:

1. 若左子树非空,则左子树上所有节点关键字值均小于根节点的关键字值。 2. 若右子树非空,则右子树上所有节点关键字值均大于根节点的关键字值。 3. 左、右子树本身也分别是一颗二叉排序树。

(ps:二叉排序树是一个递归的数据结构,且左子树节点值<根节点值<右子树节点值。由中序遍历可以得到一个递增的有序序列。)

  • 特点:二叉排序树是一种动态集合,树的结构通常不是一次生成的,而是在查找过程中,当树中不存在关键字值等于给定值得结点时再进行插入的。

1.2、基本操作

  • 1.2.2插入

若原二叉树排序树为空,则直接插入结点;

若关键字k小于根结点关键字,则插入左子树;

若关键字k大于根结点关键字,则插入右子树;

此为递归定义
int  BST_Insert(BiTree &T, KeyType k){
// 在二叉排序树T中插入一个关键字为k的结点
	if(T==NULL){
		T = (BiTree)malloc(sizeof(BSTNode));
		T->key = k;
		T->lchild=T->rchild=NULL;
		return 1;			// 返回1,表示成功
	}else if(k==T->key)		// 树中存在相同关键字的结点
		return 0;
	else if(k<T->key)		// 插入T的左子树
		return BST_Insert(T->lchild, k);
	else					// 插入T的右子树
		return BST_Insert(T->rchild, k);
}
  • 1.2.2构造

每读入一个元素,就建立一个新结点,若二叉排序树非空,则将新结点的值与根结点的值比较,若小于根结点的值,则插入左子树,否则插入右子树;若二叉排序树为空,则将新结点作为二叉排序树的根结点。

void Creat_BST(BiTree &T, KeyType str[], int n){
// 用关键字数组str[]建立二叉排序树
	T = NULL; 			// 初始化bt为空树
	int i = 0;
	while(i < n){		// 依次将每个元素插入
		BST_Insert(T, str[i]);
		i++;
	}
}
  • 1.2.4查找

查找是从根结点开始,沿某个分支逐层向下进行比较的过程。

若二叉排序树非空,则将关键字与根结点的关键字比较,若相等,则查找成功;

若不等,则当根结点的关键字值大于给定关键字值时,在根结点的左子树中查找,否则在根结点的右子树中查找。

// 非递归查找
BSTNode *BST_Search(BiTree T, ElemType key, BSTNode *&p){
// 查找函数返回指向关键字值为key的结点指针,若不存在,返回NULL;
	p = NULL;		// p指向被查找结点的双亲,用于插入和删除操作中
	while(T!=NULL&&key!=T->data){
		p = T;
		if(key<T->data)		T=T->lchild;
		else	T = T->rchild;
	}
	return T;
}
  • 1.2.3删除

删除操作的实现过程按3种情况来处理:

1.若被删除结点z是叶结点,则直接删除,不会破坏二叉排序树的性质。

2.若结点z只有左子树或右子树,则让z子树成为z父结点的子树,代替z的位置。

3.若结点z有左、右两颗子树,则令z直接后继(后直接前驱)替代z,然后从二叉排序树中删除这个直接后继(或直接前驱),这样就转换成为了第一或第二种情况。

  • 1.2.5查找效率分析

二叉排序树查找算法的平均查找长度,主要取决于树的高度。

2.平衡二叉树

2.1、定义

在插入和删除二叉树结点时,要保证任意结点的左、右子树高度差的绝对值不超过1,这样的二叉树称为平衡二叉树(Balanced Binary Tree),简称平衡树(AVL)。

目的:避免树的高度增长过快,而导致降低了二叉排序树的性能。

平衡因子:结点左子树与右子树的高度差。

2.2、基本操作1

  • 2.2.1 插入/删除
    基本思想:每当在二叉排序树中插入(或删除)一个结点时,首先检查其插入路径上的结点是否因为此次操作而导致了不平衡。若导致了不平衡,则先找到插入路径上离插入结点最近的平衡因子的绝对值大于1的结点A,再对以A为根的子树,在保持二叉排序树特性的前提下,调整各结点的位置关系,使之重心达到平衡。

失去平衡后进行调整的规律如下:

1)LL平衡旋转(右单旋转)

2)RR平衡旋转(左单旋转)

3)LR平衡旋转(先左后右双旋转)

4)RL平衡旋转(先右后左双旋转)

  • 2.2.2查找

3.哈夫曼树和哈夫曼编码

3.1、定义

树中 结点常常被赋予一个表示某种意义的数值,称为该结点的权。从树根结点到任意结点的路径长度(边数)与该结点上权值的乘积,称为该结点的带权路径长度。树中所有叶结点的带权路径长度之和称为该树的带权路径长度。

其中带权路径长度最小的二叉树称为哈夫曼树,也称为最优二叉树。

3.2、哈夫曼树的构造

  • 1、將n个结点分别作为n棵仅含一个结点的二叉树,构成森林F.
  • 2、构造一个新结点,从F中选取两棵根结点权值最小的树作为新结点的左、右子树,并且将新结点的权值置为左右子树上根结点的权值之和。
  • 3、从F中删除刚才选出的两棵树,同时将新得到的树加入F中。
  • 4、重复步骤2、3,直到F中只剩下一颗树为止。

3.3、哈夫曼编码

哈夫曼编码是一种可变长度编码,应用于数据压缩编码。

  • 首先,将每个出现的字符当做一个独立的结点,权值为它出现的频度(或次数),构造出对应的哈夫曼树。
  • 将字符的编码解释为从根至该字符的路径上边标记的序列,其中边标记为0表示"转向左孩子",标记为1表示"转向右孩子"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值