数据结构(四)——二叉搜索树和平衡二叉树

文章目录

  • 1. 二叉排序树(BST)
    • 1.1 二叉排序树的定义
    • 1.2 查找
    • 1.3 插入
    • 1.4 构造
    • 1.5 删除
  • 2. 二叉平衡树(AVL)
    • 2.1 平衡二叉树的定义
    • 2.2 插入

1. 二叉排序树(BST)

1.1 二叉排序树的定义

  • 左子树上所有节点的值小于根节点的值。
  • 右子树上所有节点的值大于根节点的值。
  • 对二叉排序树进行中序遍历,可以获得递增的有序序列。

1.2 查找

(1)思想
二叉排序树的查找是从根节点开始,自顶向下比较的过程。

  • 若相等,则查找成功。
  • 当根节点非空时,若小于根节点的值,则在左子树上查找。如大于根节点的值,则在右子树上查找。
  • 函数返回正确节点或NULL值。
/*二叉搜索树的查找(非递归版本)*/
BSTNode* BST_Search(BSTNode* T, int key)
{
	while(T != NULL && T->val != key){
		if(T->val >key)	T = T->rchild;
		else T = T->lchild;
	}
	return T;		// NULL 或 查找到的节点
}

(2)查找效率分析

  • 最好情况下:即AVL树,n个节点的二叉树最小高度为 [ log ⁡ 2 n ] + 1 [\log_2n]+1 [log2n]+1,平均查找长度为 O ( log ⁡ 2 n ) O(\log_2n) O(log2n)
  • 最坏情况,每个节点只有一个分支,树高 h = n h=n h=n,平均查找长度为 O ( n ) O(n) O(n)
    数据结构(四)——二叉搜索树和平衡二叉树_第1张图片

1.3 插入

(1)思想
二叉搜索树的插入本质上是查找的过程。

  • 若成功找到与插入值相同的节点,则插入失败。
  • 否则成功找到插入位置,在该位置插入新节点。
/*二叉搜索树的插入(递归)*/
int BST_Insert(BSTNode* T, int key)
{
	if(T == NULL)	// 找到插入位置
	{
		 T = new BSTNode(key);
		 T->lchild = T->rchild = NULL;
		 return 1;
	}
	if(T->val == key)
		return 0;	
	if(T->val > key)
		BST_Insert(T->lchild, key);
	else 
		BST_Insert(T->rchild, key);
}

1.4 构造

二叉搜索树的构造就是将给定序列值当作节点插入的过程。

BSTNode* Create_BST(int str[], int n)
{
	BSTNode* root = NULL;
	int i = 0;
	while(i <n){
		BST_Insert(root, str[i]);
		i++;
	}
	return root;
}

1.5 删除

从二叉搜索树中删除一个节点时,不能将该结点为根节点的子树一起删掉。
(1)思想

  • 当删除节点z为叶节点时,则直接删除。
  • 当删除节点z只有一颗左子树或右子树时,则让节点z的子树替代,并删除z节点。
  • 当删除节点z既有左子树又有右子树时,有两种方案:
    ①用右子树中的最小节点(最左下) 替换节点z,并删除该最小节点。
    ②用左子树中的最大节点(最右下) 替换节点z,并删除该最大节点。
    注意: 因为删除的最左下或最有下的节点不会同时具有左右两颗子树,因此将问题转化为了1、2两种情况。
    数据结构(四)——二叉搜索树和平衡二叉树_第2张图片

2. 二叉平衡树(AVL)

2.1 平衡二叉树的定义

  • 平衡因子: 结点左子树和右子树的高度差。
  • AVL: 树中的任意结点的左右子树高度差不超过1.
  • 最小不平衡子树: 插入路径上离插入节点最近的平衡因子大于1的节点作为根的子树。

2.2 插入

(1)思想
与BST插入思路类似,首先找到节点插入的位置。插入节点后,判断插入路径上的节点是否因为插入操作不平衡。若导致不平衡,则调整最小不平衡子树。

(2)4种调整规律
总的规律如下:左子树上节点右旋,右子树上节点左旋。
假设A为最小不平衡子树的根节点。

  • LL: 插入前A左子树的深度比右子树多1。在A的左孩子的左子树上插入了新节点,导致以A为根的子树失去平衡。
    方法: (右旋) 将A的左孩子B右上旋替代A成为根节点,A右下旋成为B的右孩子,B的右孩子称为A的左孩子。
    数据结构(四)——二叉搜索树和平衡二叉树_第3张图片
  • RR: 插入前A左子树的深度比右子树深度少1.在A的右子树的右子树上插入新节点,导致以A为根的子树失去平衡。
    方法: (左旋) 将A的右孩子B左上旋替代A成为根节点,A左下旋成为B的左孩子,B的左孩子成为A的右孩子。
    数据结构(四)——二叉搜索树和平衡二叉树_第4张图片
  • LR: 插入前A左子树的深度比右子树深度多1。在A的左子树的右子树上插入新节点,导致以A为根节点的树失去平衡。
    方法: (先左旋后右旋) 插入节点的父亲C先左上旋替代B成为A的左孩子,B左下旋成为C的左孩子,C的左孩子成为B的左孩子。然后节点C右上旋替代A成为根节点,A右下旋成为C的右孩子,C的右孩子成为A的左孩子。
    数据结构(四)——二叉搜索树和平衡二叉树_第5张图片
  • RL: 插入前A左子树的深度比右子树深度少1。在A的右子树的左子树上插入新节点,导致以A为根节点的树失去平衡。
    方法: (先右旋后左旋) 插入节点的父亲C先右上旋替代B,B右下旋成为C的右孩子,C的右孩子成为B的左孩子。接着C左上旋替代A成为根节点,A左下旋成为C的左孩子,C的左孩子成为A的右孩子。
    数据结构(四)——二叉搜索树和平衡二叉树_第6张图片

你可能感兴趣的:(数据结构与算法,数据结构,二叉树,树,BST,AVL)