AVL树—平衡二叉查找树

  一颗AVL树是其每个节点的左子树和右子树的高度做多差1的二叉查找树。下面几种几种情况需要进行调整满足AVL树的性质。

1.在K3节点左子树或右子树进行一次插入,如下图1,导致了K1节点出现高度不平衡,此时采用单旋调整:具体做法,抓住K2节点,使劲的摇动它,在重力的作用下,K2变成新的根,二叉查找树性质告诉我们,在原树中K1>K2,于是在新树中K1变成K2的右儿子,K3和A仍然为K2的左儿子和K1的右儿子,子树B包含在K2和K1之间,可以将其放在K1的左儿子位置。调整后如图1.2。

《AVL树—平衡二叉查找树》                                                              《AVL树—平衡二叉查找树》

            图1.1                                                                                                                                                  图1.2

2.左单旋,其做法和1的类似,这里就直接给出旋转的结果。未调整前如图2.1,调整后如图2.2。

《AVL树—平衡二叉查找树》                                                       《AVL树—平衡二叉查找树》

                 图2.1                                                                                                                                         图2.2

3.左—右双旋。先在K2和K3之间进行左旋,再在K3和K1之间进行右旋。便可达到树平衡的效果。如下图3.1、3.2、3.3.

《AVL树—平衡二叉查找树》             《AVL树—平衡二叉查找树》              《AVL树—平衡二叉查找树》

                图3.1                                                                 图3.2(图3.1   K2和K3节点间的左旋)                                图3.3(图3.2  K3和K1节点间的右旋)

4.右—左旋转,如下图4.1、4.2、4.3。

《AVL树—平衡二叉查找树》             《AVL树—平衡二叉查找树》        《AVL树—平衡二叉查找树》

        图4.1                                                                    图4.2(图4.1  K2和K3节点间的右旋)                                    图4.3(图4.2  K1和K3节点间的左旋)

实现AVL树的代码如下:

avltree.h

 

#pragma once
template<typename Comparable>
struct Node
{
	Comparable element;
	Node* left;
	Node* right;
	int height;
	Node(Comparable e,Node* l,Node* r,int h):element(e),left(l),right(r),height(h){}
};
enum MODE
{
	PRE,
	MID,
	POST
};
template<typename Comparable>
class Avltree
{
public:
	Avltree();
	Avltree(Avltree& rh);
	bool contains(Comparable x);//判断是否包含某一个元素
	Comparable findmin();       //查找树中最小的元素
	Comparable findmax();       //查找树中最大的元素
	void insert(Comparable x);  //插入元素
	void remove(Comparable x);  //删除指定的元素
	void print(MODE mode);      //输出树的全部元素
private:
	Node<Comparable>* root;
	bool contains(Comparable x,Node<Comparable>* t);//判断是否包含某一个元素
	Node<Comparable>* findmin(Node<Comparable>* t);//查找树中最小的元素
	Node<Comparable>* findmax(Node<Comparable>* t);//查找树中最大的元素
	int Height(Node<Comparable>* t);               //计算某个节点的高度
	int max(int a,int b);                          //比较两个元素的,返回最大值
	void insert(Comparable x,Node<Comparable>* &t);//插入元素
	void remove(Comparable x,Node<Comparable>* &t);//删除指定的元素
	Node<Comparable>* singleRotateRight(Node<Comparable>* &t);//右单旋转
	Node<Comparable>* doubleRotateLeft(Node<Comparable>* &t);//左—右双旋转
	Node<Comparable>* singleRotateLeft(Node<Comparable>* &t);//左单旋转
	Node<Comparable>* doubleRotateRight(Node<Comparable>* &t);//右—左双旋转
	void PrePrint(Node<Comparable>* t);                       //前序遍历输出
	void MidPrint(Node<Comparable>* t);                       //中序遍历输出
	void PostPrint(Node<Comparable>* t);                      //后序遍历输出
}; 

avltree.cpp

#include "stdafx.h"
#include"avltree.h"
#include<iostream>
using namespace std;

template<typename Comparable>
Avltree<Comparable>::Avltree()
{
	root=NULL;
}
template<typename Comparable>
Avltree<Comparable>::Avltree(Avltree& rh)
{
	root=rh.root;
}

template<typename Comparable>
bool Avltree<Comparable>::contains(Comparable x)//判断书否包含某一元素
{
	return contains(x,root);
}
template<typename Comparable>
bool Avltree<Comparable>::contains(Comparable x,Node<Comparable>* t)
{
	if(t==NULL)
		return false;
	else if(x==t->element)
		return true;
	else if(x<t->element)
		contains(x,t->left);
	else 
		contains(x,t->right);
}

template<typename Comparable>
Comparable Avltree<Comparable>::findmin()//查找最小元素
{
	return findmin(root)->left->element;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::findmin(Node<Comparable>* t)
{
	if(t==NULL)
		return NULL;
	else if(t->left->left==NULL)
		return t;
	else
		findmin(t->left);
}

template<typename Comparable>
Comparable Avltree<Comparable>::findmax()//查找最大元素
{
	return findmax(root)->right->element;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::findmax(Node<Comparable>* t)
{
	if(t==NULL)
		return NULL;
	else if(t->right->right==NULL)
		return t;
	else
		findmax(t->right);
}

template<typename Comparable>
int Avltree<Comparable>::Height(Node<Comparable>* t)//查找某一节点的高度
{
	if(t==NULL)
		return -1;
	else
		return t->height;
}

template<typename Comparable>
int Avltree<Comparable>::max(int a,int b)
{
	return a>b?a:b;
}

template<typename Comparable>
void Avltree<Comparable>::insert(Comparable x)//插入元素
{
	insert(x,root);
}
template<typename Comparable>
void Avltree<Comparable>::insert(Comparable x,Node<Comparable>* &t)
{
	if(t==NULL)
		t=new Node<Comparable>(x,NULL,NULL,0);
	else if(x<t->element)
	{
		insert(x,t->left);
		if(Height(t->left)-Height(t->right)==2)
			if(x<t->left->element)
				t=singleRotateLeft(t);
			else
				t=doubleRotateLeft(t);
	}
	else
	{
		insert(x,t->right);
		if(Height(t->right)-Height(t->left)==2)
			if(x>t->right->element)
				t=singleRotateRight(t);
			else
				t=doubleRotateRight(t);
	}
	t->height=max(Height(t->left),Height(t->right))+1;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::singleRotateRight(Node<Comparable>* &t)//右单旋转
{
	Node<Comparable>* temp=t->left;
	t->left=temp->right;
	temp->right=t;
	t->height=max(Height(t->left),Height(t->right))+1;
	temp->height=max(Height(temp->left),t->height)+1;
	return temp;
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::singleRotateLeft(Node<Comparable>* &t)//左单旋转
{
	Node<Comparable>* temp=t->right;
	t->right=temp->left;
	temp->left=t;
	t->height=max(Height(t->left),Height(t->right))+1;
	temp->height=max(Height(temp->right),t->height)+1;
	return temp;

}


template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::doubleRotateLeft(Node<Comparable>* &t)//左—右双旋转
{
	t->left=singleRotateLeft(t->left);
	return singleRotateRight(t);
}
template<typename Comparable>
Node<Comparable>* Avltree<Comparable>::doubleRotateRight(Node<Comparable>* &t)//右—左双旋转
{
	t->right=singleRotateRight(t->right);
	return singleRotateLeft(t);
}

template<typename Comparable>
void Avltree<Comparable>::remove(Comparable x)//删除元素
{
	remove(x,root);
}
template<typename Comparable>
void Avltree<Comparable>::remove(Comparable x,Node<Comparable>* &t)
{
	if(t==NULL)
		return;
	else if(x<t->element)
	{
		remove(x,t->left);
		if(Height(t->right)-Height(t->left)==2)
		{
			Node<Comparable>* temp=t->right;
			if(Height(temp->right)>=Height(temp->left))
				t=singleRotateRight(t);
			else
				t=doubleRotateRight(t);
		}

	}
	else if(x>t->element)
	{
		remove(x,t->right);
		if(Height(t->left)-Height(t->right)==2)
		{
			Node<Comparable>* temp=t->left;
			if(Height(temp->left)>=Height(temp->right))
			    t=singleRotateLeft(t);
			else
				t=doubleRotateLeft(t);
		}
	}
	else if(t->left!=NULL&&t->right!=NULL)
	{
		Node<Comparable>* temp=findmin(t->right);
		Node<Comparable>* OldNode=temp->left;
		t->element=OldNode->element;
		temp->left=NULL;
		delete OldNode;
	}
	else if(t->left!=NULL)
	{
		t=t->left;
		delete t->left;
	}
	else if(t->right!=NULL)
	{
		t=t->right;
		delete t->right;
	}
	else
	{
		Node<Comparable>* OldNode=t;
		t=NULL;
		delete OldNode;
	}
}

template<typename Comparable>
void Avltree<Comparable>::print(MODE mode)
{
	if(mode==PRE)
		PrePrint(root);
	else if(mode==MID)
		MidPrint(root);
	else if(mode==POST)
		PostPrint(root);
	else
		return;
	cout<<endl;
}

template<typename Comparable>
void Avltree<Comparable>::PrePrint(Node<Comparable>* t)
{
	if(t==NULL)
		return;
	else
	{
	cout<<t->element<<" ";
	PrePrint(t->left);
	PrePrint(t->right);
	}
}
template<typename Comparable>
void Avltree<Comparable>::MidPrint(Node<Comparable>* t)
{
	if(t==NULL)
		return;
	else
	{
		MidPrint(t->left);
		cout<<t->element<<" ";
		MidPrint(t->right);
	}
}
template<typename Comparable>
void Avltree<Comparable>::PostPrint(Node<Comparable>* t)
{
	if(t==NULL)
		return;
	else
	{
		PostPrint(t->left);
		PostPrint(t->right);
		cout<<t->element<<" ";
	}
}

AVL.cpp

// AVL.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"avltree.h"
#include"avltree.cpp"
#include<iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
	Avltree<int> a;
	a.insert(3);
	a.insert(2);
	a.insert(1);
	a.insert(4);
	a.insert(5);
	a.insert(6);
	a.insert(7);
	a.insert(16);
	a.insert(15);
	a.insert(14);
	a.insert(13);
	a.insert(12);
	a.insert(11);
	a.insert(8);
	a.insert(10);
	a.insert(9);
	a.remove(12);
	a.print(MID);
	return 0;
}

 

    原文作者:AVL树
    原文地址: https://blog.csdn.net/u010018325/article/details/11671541
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞