数据结构与算法问题 AVL二叉平衡树

AVL树本质上还是一棵二叉搜索树,它的特点是:

  1. 本身首先是一棵二叉搜索树。
  2. 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1
#include <iostream>
using namespace std;
const int LH = 1;
const int EH = 0;
const int RH = -1;
bool TRUE = 1;
bool FALSE = 0;

typedef struct BSTNode
{
	int key;
	int bf;
	BSTNode *lchild, *rchild;
}BSTNode;

//中序遍历
void inordertree(BSTNode * &root)
{
	if (root)
	{
		inordertree(root->lchild);
		cout << root->key<<",";
		inordertree(root->rchild);
	}
}

//前序遍历
void preordertree(BSTNode * &root)
{
	if (root)
	{
		cout << root->key<<",";
		preordertree(root->lchild);
		preordertree(root->rchild);
	}
}
//右旋
void R_Rotate(BSTNode * &p)
{
	BSTNode *lc = p->lchild;
	p->lchild = lc->rchild;
	lc->rchild = p;
	p = lc;
}

//左旋
void L_Rotate(BSTNode *& p)
{
	BSTNode *rc = p->rchild;
	p->rchild = rc->lchild;
	rc->lchild = p;
	p = rc;
}

void LeftBalance(BSTNode * &T)
{
	BSTNode *lc = T->lchild;
	switch (lc->bf)
	{
	case LH:
		T->bf = lc->bf = EH;
		R_Rotate(T);
		break;
	case RH:
		BSTNode *rd = lc->rchild;
		switch (rd->bf)
		{
		case LH:
			T->bf = RH;
			lc->bf = EH;
			break;
		case EH:
			T->bf = lc->bf = EH;
			lc->bf = LH;
			break;
		}
		rd->bf = EH;
		L_Rotate(T->lchild);//先左旋
		R_Rotate(T);
		break;
	}
}

void RightBalance(BSTNode *& T)
{
	BSTNode *rc = T->rchild;
	switch (rc->bf)
	{
	case RH:
		T->bf = rc->bf = EH;
		L_Rotate(T);
		break;
	case LH:
		BSTNode *ld = rc->lchild;
		switch (ld->bf)
		{
		case RH:
			T->bf = LH;
			rc->bf = EH;
			break;
		case EH:
			T->bf = rc->bf = EH;
			break;
		case LH:
			T->bf = EH;
			rc->bf = RH;
			break;
		}
		ld->bf = EH;
		R_Rotate(T->rchild);
		L_Rotate(T);
		break;

	}
}

int insertAVL(BSTNode *& t, int e, bool &taller)
{
	if (!t)
	{
		t = new BSTNode;
		t->key = e;
		t->lchild = t->rchild = NULL;
		t->bf = EH;
		taller = TRUE;

	}
	else
	{
		if (e == t->key)
		{
			taller = FALSE;
			return 0;
		}
		if (e < t->key)
		{
			if (!insertAVL(t->lchild, e,taller))
				return 0;
			if (taller)
			{
				switch (t->bf)
				{
				case LH:
					LeftBalance(t);
					taller = FALSE;
					break;
				case EH:
					t->bf = LH;
					taller = TRUE;
					break;
				case RH:
					t->bf = EH;
					taller = FALSE;
					break;

				}
			}
		}
		else
		{
			if (!insertAVL(t->rchild, e, taller))
				return 0;
			if (taller)
			{
				switch (t->bf)
				{
				case RH:
					RightBalance(t);
					taller = FALSE;
					break;
				case EH:
					t->bf = RH;
					taller = TRUE;
					break;
				case LH:
					t->bf = EH;
					taller = FALSE;
					break;
				}
			}
		}
	}
	return 1;
}

BSTNode *search(BSTNode *t, int key)
{
	BSTNode *p = t;
	while (p)
	{
		if (p->key == key)
			return p;
		else if (p->key < key)
			p = p->rchild;
		else
			p = p->lchild;
	}
	return p;
}

int main()
{
	BSTNode *root = NULL;
	BSTNode *r;
	bool taller = FALSE;
	int array[] = { 13, 24, 37, 90, 53 };
	for (int i = 0; i < 5; i++)
		insertAVL(root, array[i], taller);
	cout << "inorder traverse..." << endl;
	inordertree(root);
	cout << endl;
	cout << "preorder traverse..." << endl;
	preordertree(root);
	cout << endl;
	cout << "search key..." << endl;
	r = search(root, 37);
	if (r)
	{
		cout << r->key << endl;
	}
	else
	{
		cout << "not find" << endl;
	}
	system("pause");
	return 0;
}
时间: 2024-10-28 14:05:08

数据结构与算法问题 AVL二叉平衡树的相关文章

java项目---用java实现二叉平衡树(AVL树)并打印结果(详)

1 package Demo; 2 3 public class AVLtree { 4 private Node root; //首先定义根节点 5 6 private static class Node{ //定义Node指针参数 7 private int key; //节点 8 private int balance; //平衡值 9 private int height; //树的高度 10 private Node left; //左节点 11 private Node right;

二叉平衡树的插入和删除操作

1.      二叉平衡树 二叉排序树的时间复杂度和树的深度n有关.当先后插入的结点按关键字有序时,二叉排序树退化为单枝树,平均查找长度为(n+1)/2,查找效率比较低.提高查找效率,关键在于最大限度地降低树的深度n.因此需要在构成二叉排序树的过程中进行“平衡化”处理,使之成为二叉平衡树. 二叉平衡树,又称AVL树.它或者是一棵空树,或者是具有下列性质的树: 1)      具备二叉排序树的所有性质: 2)      左子树和右子树深度差的绝对值不超过1: 3)      左子树和右子树都是二叉

二叉树遍历的应用(路径和问题,判断是否是二叉搜索树,判断是否是二叉平衡树)

现在越发觉得关于树的问题真是千变万化,随便改一个条件又会是一个新的问题. 先序遍历求二叉树路径问题 问题:一棵二叉树每个节点包含一个整数,请设计一个算法输出所有满足条件的路径:此路径上所有节点之和等于给定值.注意此类路径不要求必须从根节点开始. 如果没有最后一个条件,这道题在leetcode上面见过,就是采取先序遍历的方式并记录下路径.但是加上最后一个条件后需要转下弯思考一下. 当然也需要记录下路径,并且记得要回溯.加上不要求从根节点开始这个条件后可以这么思考,每次遍历到当前节点时,从路径中查找

二叉树--二叉平衡树

二叉平衡树是二叉树中最为最要的概念之一,也是在语言库或者项目中应用比较广泛的一种特殊的树形结构. 二叉平衡树 AVL树是高度平衡的而二叉树.它的特点是:AVL树中任何节点的两个子树的高度最大差别为1. 通常AVL树是在二叉搜索树上,经过局部调整而建立的,因此,它还是一棵排序树. 上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1:而右边的不是AVL树,因为7的两颗子树的高度相差为2(以2为根节点的树的高度是3,而以8为根节点的树的高度是1). 性质 左右子树相差不超过1.

普林斯顿公开课 算法4-2:二叉堆

二叉树 介绍二叉堆之前首先介绍二叉树.二叉树有一个根节点,节点下又有两个子节点.完全二叉树是指一个二叉树树除了最底层,其他层都是完全平衡的. 完全二叉树最基本的性质就是它的高度是 floor(lgN). 二叉堆 二叉堆是完全二叉树的一种,每个节点对应一个数值,而且这个数值都大于等于它子节点的数值. 下图是一个二叉堆. 二叉堆的储存 由于二叉堆是完全二叉树,所以它可以用一个数组进行储存.所以不需要创建节点对象,再建立节点之间的连接.这样节省了很多开销. 用数组a[]表示一个二叉堆有以下特性: a[

二叉平衡树之删除节点

二叉平衡树之删除节点操作 更好的判断最小非平衡树类型的方法 在前一篇文章中,我们知道最小非平衡树可以分为四种类型,即:LL型.LR型.RR型和RL型.而且我也按照自己的理解,归纳了判断是哪种类型的方法.总结一下就是:设最小非平衡树的树根为unbalance,首先看unbalance的左右子树谁更高,如果左子树更高则为LX型.如果是右子树高则为RX型.再进一步,如果为LX型,将刚刚插入的节点的值value与unbalance左孩子进行比较,如果value大则为LR型,如果value小则为LL型.如

判断一颗二叉树是否为二叉平衡树 python 代码

输入一颗二叉树,判断这棵树是否为二叉平衡树.首先来看一下二叉平衡树的概念:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.因此判断一颗二叉平衡树的关键在于求出左右子树的高度差,而二叉树的高度又是怎么定义的呢?二叉树的高度指的是从根节点到叶子节点所有路径上包含节点个数的最大值.所以我们可以得出,父亲节点的高度与左右子树高度的关系为:父亲节点的高度=max(左子树高度,右子树高度)+1,同时我们知道,叶子节点的高度值为1(或则0,这里定义1或者0对判断结

纯数据结构Java实现(6/11)(二叉堆&amp;优先队列)

堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). 但是二叉堆,需要满足一些特殊性质: 其一.二叉堆一定是一棵完全二叉树 (完全二叉树可以用数组表示,见下面) 完全二叉树缺失的部分一定是在右下方.(每层一定是从左到右的顺序优先存放) 完全二叉树的结构,可以简单理解成按层安放元素的.(所以数组是不错的底层实现) 其二.父节点一定比子节点大 (针对大顶堆

【算法导论】二叉搜索树

什么是二叉搜索树 顾名思义,一棵二叉搜索树是以一棵二叉树来组织的.这样一棵树可以使用一个链表数据结构来表示,其中每个结点就是一个对象.除了key和卫星数据之外,每个结点还包含属性left.right和p,它们分别指向结点的左孩子.右孩子和双亲.如果某个孩子结点和父结点不存在,则相应属性的值为NIL.根结点是树中唯一父指针为NIL的结点. 二叉搜索树中的关键字总是以满足二叉搜索树性质的方式来存储: 设x是二叉搜索树中的一个结点.如果y是x左子树中的一个结点,那么 y.key <= x.key.如果