平衡二叉搜索树

  任何结点的左子树和右子树高度最多相差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》平衡二叉搜索树相关推荐

  1. VC++2012编程演练数据结构《3》堆栈实现进制转换

    栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表.它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出 ...

  2. VC++2012编程演练数据结构《12》二叉排序树

    二叉排序树(Binary Sort Tree)又称二叉查找树. 它或者是一棵空树:或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则 ...

  3. VC++2012编程演练数据结构《25》线索二叉树

    线索二叉树 按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列.在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结点. ...

  4. VC++2012编程演练数据结构《35》多路平衡归并

    多路平衡归并 一般说来,如果初始归并段有m个,那么这样的二路归并树就有élog2mù+1层,要对数据进行élog2mù遍扫描.采用k路平衡归并时,则相应的归并树有élogkmù+1层,要对数据进行él ...

  5. VC++2012编程演练数据结构《31》狄杰斯特拉算法

    狄杰斯特拉算法 Dijkstra(狄杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很 ...

  6. VC++2012编程演练数据结构《36》磁盘文件进行排序

    如何给磁盘文件排序 问题描述: 输入:一个最多含有n个不相同的正整数的文件,其中每个数都小于等于n,且n=10^7. 输出:得到按从小到大升序排列的包含所有输入的整数的列表. 条件:最多有大约1MB的 ...

  7. 《恋上数据结构第1季》平衡二叉搜索树、AVL树

    AVL树 二叉搜索树缺点分析 改进二叉搜索树 平衡(Balance) 理想平衡 如何改进二叉搜索树? 平衡二叉搜索树(Balanced Binary Search Tree) AVL树 BST 对比 ...

  8. 数据结构与算法-平衡二叉搜索树

    平衡二叉搜索树 1.自平衡的二叉搜索树 2.平衡 (1)空树平衡 (2)非空树平衡 左右子树平衡 左右子树高度差绝对值 <= 1 3.平衡因子 左右子树的高度差的衡量值 -1 0 1 (一)平衡 ...

  9. 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

    在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉 ...

最新文章

  1. Android开发工具
  2. pythonweb开发-5个最好的Python Web开发框架
  3. C++LU decomposition(LU分解)的实现算法(附完整源码)
  4. Spark的基本架构
  5. 图解安装CentOS 6.6
  6. 前端学习(2159):vuecli脚手架的配置和安装
  7. ansible安装和基本使用
  8. vue element form 默认校验
  9. 为什么感觉农村人在城里工作后,大部分都变了?
  10. SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
  11. 多进程——守护进程例子
  12. DFA敏感词过滤算法详解
  13. ios定位权限plist_[译] iOS 请求定位权限
  14. EML-NET: An Expandable Multi-Layer NETwork for Saliency Prediction【论文笔记】
  15. 问题 F: 是你飘了,还是我拿不动刀了(字符串问题)
  16. “华为杯“ 武汉大学21级新生程序设计竞赛错题笔记
  17. 10个提升效率的编程好习惯
  18. 【机器学习】极大似然估计、最大后验估计的对比与联系
  19. uva 10306 e-Coin
  20. 抬杠APP获Donews“年度最佳运营创意”大奖,跨界营销引瞩目

热门文章

  1. BI数据分析从业者从零开始学习财务知识?有哪些入门书籍推荐
  2. 电信业服务流程设计--用例图
  3. html首行缩进2字符,可以使用CSS属性中的【text-indent】进行设置。
  4. CoordConv:给卷积加上坐标,从而使其具备了空间感知能力【附Pytorch实现】
  5. js强制保留两位小数
  6. 同一主机下进程间的通信方式
  7. Windows下面搭建在线文档工具showdoc工具
  8. 怎么建立软连接和删除软连接、宏定义个声明一年有多少秒、关于自定义函数类型指针
  9. 如何学习投资 推荐几本教材
  10. 网站流量过大服务器不行,网站如何应对突然的大流量访问?