平衡二叉树的插入实现

原创 2013年12月08日 22:01:22

平衡二叉树的是指左右子树的高度相差不超过1的二叉查找树,要实现平衡二叉树,我们只要在二叉查找树插入结点的时候保证左右子树的高度相差不超过1即可。


一. 平衡二叉树的插入。

现在考虑两种情况:

1. 插入新的结点后树还满足平衡二叉树的性质,也就是说左右子树的高度差不超过1,那么我们只需要根据现在的左右子树情况设置一下树的状态即可,也就是现在是左子树高或者是右子树高,还是左右子树的高度相等。

2. 插入新的结点后树的子树高度差变成了2,那么现在树已经不满足平衡二叉树的性质了,所以需要调整树的结点,也就是需要对树进行旋转。

我们现在考虑2的情况下,树应该怎么旋转。

我们先看插入结点后,树的平衡情况(假设新节点是插入到了右子树,用right_tree表示):

case1:right_tree的右子树高

插入结点后,right_tree的右子树比左子树要高,那么我们就要向左旋转,看下图:

通过向左旋转后,树重新达到了平衡,之前的root结点变成了左结点,right_tree上升为跟结点。

case2:right_tree的左子树高

插入结点后,right_tree的左子树要比右子树高,这个情况比较复杂,树需要旋转两次才可以重新达到平衡,看下图:

right_tree先向右旋转一次,sub_tree上升一级,right_tree成为sub_tree的右子结点,然后跟结点再左旋转一次,最后sub_tree上升为跟结点,root变为左子结点,right_tree还是右子结点,但是sub_tree原先的左右子树T2和T3分别变成了root的右子树和right_tree的左子树。

case3:right_tree的左右子树高度相等

这种情况不可能存在,因为如果right_tree的左右子树高度相等,说明插入新节点后right_tree的高度没有发生变化,这和root的左右子树高度已经相差2矛盾。

下面是实现的核心代码:

template<class Record>
Error_code AVL_tree<Record>::insert(const Record &new_data)
{
	bool taller;
	return avl_insert(root,new_data,taller);
}


template<class Record>
Error_code AVL_tree<Record>::avl_insert(AVL_node<Record> *&sub_root, const Record &new_data, bool &taller)
{
	if (sub_root == NULL)
	{
		sub_root = new AVL_node<Record>(new_data);
		taller = true;
		return success;
	}
	else if (new_data == sub_root->data)
	{
		taller = false;
		return duplicate_error;
	}
	else if (new_data < sub_root->data)
	{
		avl_insert(sub_root->left, new_data, taller);
		if (taller == true)
		{
			switch(sub_root->get_balance())
			{
			case left_higher:
				left_balance(sub_root);
				taller = false;
				break;
			case equal_height:
				sub_root->set_balance(left_higher);
				break;
			case right_higher:
				sub_root->set_balance(equal_height);
				taller = false;
				break;
			}
		}
	}
	else
	{
		avl_insert(sub_root->right, new_data, taller);
		if (taller == true)
		{
			switch(sub_root->get_balance())
			{
			case left_higher:
				sub_root->set_balance(equal_height);
				taller = false;
				break;
			case equal_height:
				sub_root->set_balance(right_higher);
				break;
			case right_higher:
				right_balance(sub_root);
				taller = false;
				break;
			}
		}
	}
}

template<class Record>
void AVL_tree<Record>::left_balance(AVL_node<Record> *&sub_root)
{
	AVL_node<Record> *&left_tree = sub_root->left;
	switch(left_tree->get_balance())
	{
	case left_higher:
		sub_root->set_balance(equal_height);
		left_tree->set_balance(equal_height);
		rotate_right(sub_root);
		break;
	case equal_height:
		cout << "impossible case" << endl;
		break;
	case right_higher:
		AVL_node<Record> *sub_tree = left_tree->right;
		switch(sub_tree->get_balance())
		{
		case equal_height:
			sub_root->set_balance(equal_height);
			left_tree->set_balance(equal_height);
			break;
		case left_higher:
			sub_root->set_balance(right_higher);
			left_tree->set_balance(equal_height);
			break;
		case right_higher:
			sub_root->set_balance(equal_height);
			left_tree->set_balance(left_higher);
			break;
		}
		sub_tree->set_balance(equal_height);
		rotate_left(left_tree);
		rotate_right(sub_root);
		break;
	}
}

template<class Record>
void AVL_tree<Record>::right_balance(AVL_node<Record> *&sub_root)
{
	AVL_node<Record> *&right_tree = sub_root->right;
	switch(right_tree->get_balance())
	{
	case right_higher:
		sub_root->set_balance(equal_height);
		right_tree->set_balance(equal_height);
		rotate_left(sub_root);
		break;
	case equal_height:
		cout << "impossible case" << endl;
		break;
	case left_higher:
		AVL_node<Record> *sub_tree = right_tree->left;
		switch(sub_tree->get_balance())
		{
		case equal_height:
			sub_root->set_balance(equal_height);
			right_tree->set_balance(equal_height);
			break;
		case left_higher:
			sub_root->set_balance(equal_height);
			right_tree->set_balance(right_higher);
			break;
		case right_higher:
			sub_root->set_balance(left_higher);
			right_tree->set_balance(equal_height);
			break;
		}
		sub_tree->set_balance(equal_height);
		rotate_right(right_tree);
		rotate_left(sub_root);
		break;
	}
}


template<class Record>
void AVL_tree<Record>::rotate_left(AVL_node<Record> *&sub_root)
{
	AVL_node<Record> *right_tree = sub_root->right;
	sub_root->right = right_tree->left;
	right_tree->left = sub_root;
	sub_root = right_tree;
}

template<class Record>
void AVL_tree<Record>::rotate_right(AVL_node<Record> *&sub_root)
{
	AVL_node<Record> *left_tree = sub_root->left;
	sub_root->left = left_tree->right;
	left_tree->right = sub_root;
	sub_root = left_tree;
}


相关文章推荐

C语言实现平衡二叉树

  • 2015年08月10日 22:21
  • 7KB
  • 下载

AVL Tree 平衡二叉树基本插入删除节点功能的实现

简述: 实现AVL 树,主要是两个功能 : 插入某节点和删除某节点 AVL Tree的定义, 1. 是一棵二叉搜索树(故而每个节点是惟一的, 如果出现重复数字会破坏平衡树的算法) 2....
  • anialy
  • anialy
  • 2012年09月18日 20:40
  • 10265

平衡二叉树-红黑树的实现

  • 2017年05月12日 21:30
  • 20KB
  • 下载

平衡二叉树C++实现

  • 2016年01月06日 21:39
  • 3.35MB
  • 下载

平衡二叉树(AVL)的插入、删除、查找的java实现

平衡二叉树(AVL)操作实现java代码 package ccnu.offer.tree;// 平衡二叉树(AVL树)的avl实现 // AVL树只是实现平衡二叉树的一种方法,它还有很多的其他实现方法...

平衡二叉树实现

  • 2017年06月30日 14:55
  • 17KB
  • 下载

平衡二叉树(AVL)--查找、删除、插入(Java实现)

前言                        前面一篇文章,笔者就二叉查找树进行了一些解释与实现,这篇文章笔者将会就平衡二叉树                    做一些总结与实现。读者若...
  • kiritor
  • kiritor
  • 2013年05月08日 10:11
  • 7769

数据结构之平衡二叉树的递归实现

  • 2016年12月05日 22:59
  • 10.94MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:平衡二叉树的插入实现
举报原因:
原因补充:

(最多只允许输入30个字)