VC++2012编程演练数据结构《9》平衡二叉搜索树

平衡二叉搜索树

  任何结点的左子树和右子树高度最多相差1的二叉搜索树。
  (1)AVL树的插入算法
  a. 插入结点之后仍然是AVL树,则不调整;
  b. 插入结点之后不再满足AVL树条件,则进行调整,根据导致不平衡的原因,分为:
  a) LL型――单旋转调整
  b) LR型――双旋转调整
  c) RL型――双旋转调整
  d) RR型――单旋转调整
  下图是顺序插入单词{cup,cop,copy,hit,hi,his,hia}后得到的AVL树,单词之间按照字典顺序比较:
  (2)AVL树的删除算法
  a. 删除过程如BST结点的删除算法

  b. 删除后调整――从被删除的结点找到祖父结点,然后开始单旋转或多旋转操作,一次旋转结束并不 意味着树已经平衡,因为这可能会导致它的祖先结点发生新的不平衡。所以这样的调整操作要一直进行下去,直到树平衡为止。

类的实现如下

//平衡二叉搜索树类定义与实现
template<class T> class BSTree;
//平衡二叉搜索树的结点类型定义
template<class T> struct TNode
{private:
TNode<T>  *left;//左子树指针
TNode<T> *right;//右子树指针
public:
	int balance;//平衡因子
	T data;//数据域
	friend class BSTree<T>;
	//构造函数
	TNode():left(NULL),right(NULL),balance(0){ }
	TNode(T item,TNode<T> *left1,TNode<T> *right1)
		:balance(0),data(item),left(left1),right(right1){ }
};
template<class T> class BSTree
{private:
int size;
public:
	//构造函数
	BSTree(TNode<T> *&root):size(0){root=NULL;}
	//被ClearBST()所调用的函数
	void DeleteTree(TNode<T> *&root);
	//LL型调整操作
	void LL(TNode<T> **a,TNode<T> **b);
	//RR型调整操作
	void RR(TNode<T> **a,TNode<T> **b);
	//LR型调整操作
	void LR(TNode<T> **a,TNode<T> **b);
	//RL型调整操作
	void RL(TNode<T> **a,TNode<T> **b);
	//释放空间
	void FreeBST(TNode<T> *&root);
	//求平衡二叉搜索树中所有结点数
	int BSTSize();
	//判断平衡二叉搜索树是否为空
	int BSTEmpty(TNode<T> *&root);
	//取根指针
	TNode<T> *GetRoot(TNode<T> *&root);
	//从平衡二叉搜索树中查找元素
	TNode<T> *BSTLocate(TNode<T> *&root,T item);
	//向平衡二叉搜索树中插入元素
	void BSTInsert(TNode<T> *&root,T item);
	//中序遍历平衡二叉搜索树中的所有结点
	void Inorder(TNode<T> *&root);
	//求平衡二叉搜索树的深度
	int BSTreeDepth(TNode<T> *&root);
	//求平衡二叉搜索树中所有结点数
	int BSTreeCount(TNode<T> *&root);
	//求平衡二叉搜索树中所有叶子结点数
	int BSTreeLeafCount(TNode<T> *&root);
	//清除平衡二叉搜索树,使之变为一棵空树
	void ClearBST(TNode<T> *&root);
	//初始化平衡二叉搜索树
	void SetTNode(TNode<T> *&root,T item);
	//获取设置的平衡二叉搜索树的一个结点
	TNode<T> *GetTNode(T item,TNode<T> *left,TNode<T> *right);
};
//平衡二叉搜索树的类实现
template<class T>
void BSTree<T>::DeleteTree(TNode<T> *&root)
{if(root==NULL) return;
if(root->left!=NULL)
DeleteTree(root->left);
if(root->right!=NULL)
DeleteTree(root->right);
free(root);
}
template<class T>
void BSTree<T>::LL(TNode<T> **a,TNode<T> **b)
{(*a)->balance=0;
(*a)->left=(*b)->right;
(*b)->balance=0;
(*b)->right=(*a);
}
template<class T>
void BSTree<T>::RR(TNode<T> **a,TNode<T> **b)
{(*a)->balance=0;
(*a)->right=(*b)->left;
(*b)->balance=0;
(*b)->left=(*a);
}
template<class T>
void BSTree<T>::LR(TNode<T> **a,TNode<T> **b)
{TNode<T> *c;
c=(*b)->right;//c是插入结点
(*a)->left=c->right;
(*b)->right=c->left;
c->left=(*b);
c->right=(*a);
switch(c->balance)
{case 0:(*a)->balance=0;
(*b)->balance=0;
break;
case 1:(*a)->balance=-1;//插入的结点在c的左子树
	(*b)->balance=0;
	break;
case -1:(*a)->balance=0;//插入的结点在c的右子树
	(*b)->balance=1;
	break;}
c->balance=0;
(*b)=c;//使b指向调整后的子树的根
}
template<class T>
void BSTree<T>::RL(TNode<T> **a,TNode<T> **b)
{TNode<T> *c;
c=(*b)->left; //c是插入结点
(*a)->right=c->left;
(*b)->left=c->right;
c->right=(*b);
c->left=(*a);
switch(c->balance)
{case 0:(*a)->balance=0;
(*b)->balance=0;
break;
case 1:(*a)->balance=0;//插入的结点在c的左子树
	(*b)->balance=-1;
	break;
case -1:(*a)->balance=1;//插入的结点在c的右子树
	(*b)->balance=0;
	break;}
c->balance=0;
(*b)=c;//使b指向调整后的子树的根
}
template<class T>
void BSTree<T>::FreeBST(TNode<T> *&root)
{DeleteTree(root);}
template<class T>
int BSTree<T>::BSTSize()
{return(size);}
template<class T>
int BSTree<T>::BSTEmpty(TNode<T> *&root)
{if(root==NULL) return(1);
else return(0);}
template<class T>
TNode<T> *BSTree<T>::GetRoot(TNode<T> *&root)
{return(root);}
template<class T>
TNode<T> *BSTree<T>::BSTLocate(TNode<T> *&root,T item)
{TNode<T> *t;
t=root;
while(t!=NULL)
{if(item==t->data) break;
else
if(item<t->data) t=t->left;
else t=t->right;}
return(t);
}
template<class T>
void BSTree<T>::BSTInsert(TNode<T> *&root,T item)
{TNode<T> *t,*p,*newN,*a,*b,*f;
newN=new TNode<T>;
newN->data=item;
if(root==NULL)
{root=newN;
size++;
return;}
t=root;p=NULL;
a=t;f=p;
while(t!=NULL)
{if(t->balance!=0)
{a=t;f=p;}
p=t;
if(item<t->data) t=t->left;
else t=t->right;}
if(item<p->data) p->left=newN;
else p->right=newN;
size++;
if(item<a->data)
{b=t=a->left;}
else {b=t=a->right;}
while(t!=NULL&&t->data!=item)
{if(item<t->data)
{t->balance=1;
t=t->left;}
else {t->balance=-1;t=t->right;}}
if(a->balance==0)
{if(item<a->data) a->balance=1;
else a->balance=-1;
return;}
else
if(item<a->data&&a->balance==-1||
   item>a->data&&a->balance==1)
{a->balance=0;return;}
else
{if(a->balance==1)
if(b->balance==1)
LL(&a,&b);
else LR(&a,&b);
else
if(b->balance==-1) RR(&a,&b);
else RL(&a,&b);}
if(f==NULL) root=b;
else
{if(f->left==a) f->left=b;
else f->right=b;}
}
template<class T>
void BSTree<T>::Inorder(TNode<T> *&root)
{if(root!=NULL) {
	Inorder(root->left);
	cout<<setw(2)<<root->data;
	Inorder(root->right);}
}
template<class T>
int BSTree<T>::BSTreeDepth(TNode<T> *&root)
{if(root==NULL) return 0;
else
{  //计算左子树的深度
	int dep1=BSTreeDepth(root->left);
	//计算右子树的深度
	int dep2=BSTreeDepth(root->right);
	//返回树的深度
	if(dep1>dep2) return dep1+1;
	else return dep2+1;}
}
template<class T>
int BSTree<T>::BSTreeCount(TNode<T> *&root)
{if(root==NULL) return 0;
else 
return BSTreeCount(root->left)+BSTreeCount(root->right)+1;
}
template<class T>
int BSTree<T>::BSTreeLeafCount(TNode<T> *&root)
{if(root==NULL) return 0;
else
if(root->left==NULL && root->right==NULL) return 1;
else
return BSTreeLeafCount(root->left)+BSTreeLeafCount(root->right);
}
template<class T>
void BSTree<T>::ClearBST(TNode<T> *&root)
{DeleteTree(root);
root=NULL;
size=0;
}
template<class T>
void BSTree<T>::SetTNode(TNode<T> *&root,T item)
{root->data=item;
root->balance=0;
root->left=NULL;
root->right=NULL;
}
template<class T>
TNode<T>* BSTree<T>::GetTNode(T item,TNode<T> *left,TNode<T> *right)
{TNode<T> *ptr;
ptr=new TNode<T>;
ptr->data=item;
ptr->balance=0;
ptr->left=left;
ptr->right=right;
return(ptr);
}



调用如下

#include<conio.h>
#include<stdlib.h>
#include "AVLTREE.h"
using namespace std;
TNode<char> *q;
void main()
{cout<<"运行结果:\n";
int i;
char test[50]="abxyMNcdefgqwertyuizxcvbnm";
BSTree<char> t(q);
//cout<<"input data:\n";
//gets(test);
for(i=0;test[i]!='\0';i++)
t.BSTInsert(q,test[i]);
cout<<"平衡二叉搜索树的结点数="<<t.BSTSize()<<endl;
cout<<"平衡二叉搜索树的结点数="<<t.BSTreeCount(q)<<endl;
cout<<"平衡二叉搜索树的深度="<<t.BSTreeDepth(q)<<endl;
cout<<"平衡二叉搜索树的叶子结点数="<<t.BSTreeLeafCount(q)<<endl;
cout<<"中序遍历平衡二叉搜索树:\n";
t.Inorder(q);
getch();
t.FreeBST(q);
}



效果如下



代码下载如下

http://download.csdn.net/detail/yincheng01/4785937


原文地址:https://www.cnblogs.com/new0801/p/6177657.html