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
VC++2012编程演练数据结构《9》平衡二叉搜索树相关推荐
- VC++2012编程演练数据结构《3》堆栈实现进制转换
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表.它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出 ...
- VC++2012编程演练数据结构《12》二叉排序树
二叉排序树(Binary Sort Tree)又称二叉查找树. 它或者是一棵空树:或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则 ...
- VC++2012编程演练数据结构《25》线索二叉树
线索二叉树 按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列.在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结点. ...
- VC++2012编程演练数据结构《35》多路平衡归并
多路平衡归并 一般说来,如果初始归并段有m个,那么这样的二路归并树就有élog2mù+1层,要对数据进行élog2mù遍扫描.采用k路平衡归并时,则相应的归并树有élogkmù+1层,要对数据进行él ...
- VC++2012编程演练数据结构《31》狄杰斯特拉算法
狄杰斯特拉算法 Dijkstra(狄杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很 ...
- VC++2012编程演练数据结构《36》磁盘文件进行排序
如何给磁盘文件排序 问题描述: 输入:一个最多含有n个不相同的正整数的文件,其中每个数都小于等于n,且n=10^7. 输出:得到按从小到大升序排列的包含所有输入的整数的列表. 条件:最多有大约1MB的 ...
- 《恋上数据结构第1季》平衡二叉搜索树、AVL树
AVL树 二叉搜索树缺点分析 改进二叉搜索树 平衡(Balance) 理想平衡 如何改进二叉搜索树? 平衡二叉搜索树(Balanced Binary Search Tree) AVL树 BST 对比 ...
- 数据结构与算法-平衡二叉搜索树
平衡二叉搜索树 1.自平衡的二叉搜索树 2.平衡 (1)空树平衡 (2)非空树平衡 左右子树平衡 左右子树高度差绝对值 <= 1 3.平衡因子 左右子树的高度差的衡量值 -1 0 1 (一)平衡 ...
- 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树
在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉 ...
最新文章
- Android开发工具
- pythonweb开发-5个最好的Python Web开发框架
- C++LU decomposition(LU分解)的实现算法(附完整源码)
- Spark的基本架构
- 图解安装CentOS 6.6
- 前端学习(2159):vuecli脚手架的配置和安装
- ansible安装和基本使用
- vue element form 默认校验
- 为什么感觉农村人在城里工作后,大部分都变了?
- SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
- 多进程——守护进程例子
- DFA敏感词过滤算法详解
- ios定位权限plist_[译] iOS 请求定位权限
- EML-NET: An Expandable Multi-Layer NETwork for Saliency Prediction【论文笔记】
- 问题 F: 是你飘了,还是我拿不动刀了(字符串问题)
- “华为杯“ 武汉大学21级新生程序设计竞赛错题笔记
- 10个提升效率的编程好习惯
- 【机器学习】极大似然估计、最大后验估计的对比与联系
- uva 10306 e-Coin
- 抬杠APP获Donews“年度最佳运营创意”大奖,跨界营销引瞩目