数据结构与算法——AVL树类的C++实现
关于AVL树的简单介绍能够參考:数据结构与算法——AVL树简单介绍
关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法——二叉查找树类的C++实现
AVL-tree是一个"加上了额外平衡条件"的二叉搜索树,其平衡条件的建立是为了确保整棵树的深度为O(logN)。要求不论什么节点的左右子树高度相差最多1。
该AVL树结点的数据结构:
- struct AvlNode{
- Comparable element;
- AvlNode * left;
- AvlNode * right;
- int height;
- AvlNode(const Comparable & e, AvlNode * lt, AvlNode * rt, int h = 0):element(e), left(lt), right(rt), height(h){}
- };
该结点数据结构事实上是一个结点类。
该AVL树的主要成员函数:
- void makeEmpty();//清空该树
- bool isEmpty() const;//推断该树是否为空
- void lessOrderPrintTree();//从小到大输出该AVL平衡树
- void biggerOrderPrintTree();//从大到小输出该AVL平衡树
- void insert(const Comparable & x);//插入值为x的结点
- Comparable findMin() const;//找到最小值
- Comparable findMax() const;//找到最大值
主要成员函数介绍:
- /****************************************************************
- * 函数名称:void insert(const Comparable & x, AvlNode * t)
- * 功能描写叙述: 在结点t的后面插入值为x的结点
- * 參数列表: x为要插入结点的值
- * t为当前的结点
- * 返回结果:void
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::insert(const Comparable & x, AvlNode * & t)
- {
- if(t == NULL)//当前结点为空
- t = new AvlNode(x, NULL, NULL);
- else if(x < t->element){
- insert(x, t->left);
- if(height(t->left) - height(t->right) == 2){
- if(x < t->left->element)//单旋转。左左插入
- rotateWithLeftChild(t);
- else
- doubleWithLeftChild(t);//双旋转。左右插入
- }
- }
- else if(x > t->element){
- insert(x, t->right);
- if(height(t->right) - height(t->left) == 2){
- if(x > t->right->element)//单旋转,右右插入
- rotateWithRightChild(t);
- else
- doubleWithRightChild(t);//双旋转,右左插入
- }
- }
- //假设x的值和当前结点的值同样,则忽略。
- 也能够向之前二叉查找树一样给每一个结点再加一个num成员变量。
- t->height = max(height(t->left), height(t->right)) + 1;//更新结点t的高度
- }
- /****************************************************************
- * 函数名称:rotateWithLeftChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行单旋转。用于左左插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::rotateWithLeftChild(AvlNode * & k2)
- {
- cout << "左单旋转" << endl;
- AvlNode * k1 = k2->left;
- k2->left = k1->right;
- k1->right = k2;
- k2->height = max(height(k2->left), height(k2->right)) + 1;
- k1->height = max(height(k1->left), k2->height) + 1;
- k2 = k1;
- }
- /****************************************************************
- * 函数名称:rotateWithRightChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行单旋转。用于左右插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::rotateWithRightChild(AvlNode * & k1)
- {
- cout << "右单旋转" << endl;
- AvlNode * k2 = k1->right;
- k1->right = k2->left;
- k2->left = k1;
- k1->height = max(height(k1->left), height(k1->right)) + 1;
- k2->height = max(height(k2->right), k1->height) + 1;
- k1 = k2;
- }
- /****************************************************************
- * 函数名称:doubleWithLeftChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行双旋转,用于左右插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::doubleWithLeftChild(AvlNode * & k3)
- {
- cout << "**********************" << endl;
- cout << "左双旋转: " << endl;
- rotateWithRightChild(k3->left);
- rotateWithLeftChild(k3);
- cout << "**********************" << endl;
- }
- /****************************************************************
- * 函数名称:doubleWithRightChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行双旋转。用于右左插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::doubleWithRightChild(AvlNode * & k1)
- {
- cout << "**********************" << endl;
- cout << "右双旋转: " << endl;
- rotateWithLeftChild(k1->right);
- rotateWithRightChild(k1);
- cout << "**********************" << endl;
- }
关于右单旋转的一个图例:
结合图形看该旋转函数:
- template<typename Comparable>
- void AvlTree<Comparable>::rotateWithRightChild(AvlNode * & k1)
- {
- cout << "右单旋转" << endl;
- AvlNode * k2 = k1->right;
- k1->right = k2->left;
- k2->left = k1;
- k1->height = max(height(k1->left), height(k1->right)) + 1;
- k2->height = max(height(k2->right), k1->height) + 1;
- k1 = k2;
- }
左单旋转是相同的道理。
关于右双旋转的一个图例:
结合图形看该旋转函数:
- template<typename Comparable>
- void AvlTree<Comparable>::doubleWithRightChild(AvlNode * & k1)
- {
- cout << "**********************" << endl;
- cout << "右双旋转: " << endl;
- rotateWithLeftChild(k1->right);
- rotateWithRightChild(k1);
- cout << "**********************" << endl;
- }
该函数中的凝视是为了測试该函数是否运行了。
以下给出一个完整的实測:
- AvlTree<int> tree2;
- cout << "构造AVL树trre2: " << endl;
- for(int i = 1; i < 8; ++i)
- tree2.insert(i);
- tree2.insert(16);
- tree2.insert(15);
- tree2.lessOrderPrintTree();
- tree2.biggerOrderPrintTree();
输出为:
右单旋转
右单旋转
右单旋转
右单旋转
**********************
右双旋转:
左单旋转
右单旋转
**********************
从小到大输出:1 2 3 4 5 6 7 15 16
从大到小输出:16 15 7 6 5 4 3 2 1
以下是该AVL树类的源码:
- /*************************************************************************
- > File Name: AvlTree.cpp
- > Author:
- > Mail:
- > Created Time: 2016年04月08日 星期五 10时14分48秒
- ************************************************************************/
- #include <iostream>
- #include <algorithm>
- #include <vector>
- using namespace std;
- template<typename Comparable>
- class AvlTree{
- public:
- AvlTree(){ root = NULL; }
- ~AvlTree();
- void makeEmpty();//清空该树
- bool isEmpty() const;//推断该树是否为空
- void lessOrderPrintTree();//从小到大输出该AVL平衡树
- void biggerOrderPrintTree();//从大到小输出该AVL平衡树
- void insert(const Comparable & x);//插入值为x的结点
- Comparable findMin() const;//找到最小值
- Comparable findMax() const;//找到最大值
- private:
- struct AvlNode{
- Comparable element;
- AvlNode * left;
- AvlNode * right;
- int height;
- AvlNode(const Comparable & e, AvlNode * lt, AvlNode * rt, int h = 0):element(e), left(lt), right(rt), height(h){}
- };
- AvlNode * root;
- private:
- void makeEmpty(AvlNode * t);
- void lessOrderPrintTree(AvlNode * t);
- void biggerOrderPrintTree(AvlNode * t);
- int height(AvlNode * t) const;//获得当前结点t的高度
- void insert(const Comparable & x, AvlNode * & t);//在t处。插入值为x的结点
- void rotateWithLeftChild(AvlNode * & k2);//单旋转,左左插入的情况
- void rotateWithRightChild(AvlNode * & k1);//单旋转,右右插入的情况
- void doubleWithLeftChild(AvlNode * & k3);//双旋转。左右插入的情况
- void doubleWithRightChild(AvlNode * & k1);//双旋转。右左插入的情况
- Comparable findMin(AvlNode * t) const;//找到最小值
- Comparable findMax(AvlNode * t) const;//找到最大值
- };
- /****************************************************************
- * 函数名称:findMax()
- * 功能描写叙述: 找到该树的最大值
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- Comparable AvlTree<Comparable>::findMax() const
- {
- if(!isEmpty())
- return findMax(root);
- }
- /****************************************************************
- * 函数名称:findMax(AvlNode * t)
- * 功能描写叙述: 找到该树的最大值
- * 參数列表: t表示当前结点
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- Comparable AvlTree<Comparable>::findMax(AvlNode * t) const
- {
- if(t->right== NULL)
- return t->element;
- else
- return findMax(t->right);
- }
- /****************************************************************
- * 函数名称:findMin()
- * 功能描写叙述: 找到该树的最小值
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- Comparable AvlTree<Comparable>::findMin() const
- {
- if(!isEmpty())
- return findMin(root);
- }
- /****************************************************************
- * 函数名称:findMin(AvlNode * t)
- * 功能描写叙述: 找到该树的最小值
- * 參数列表: t表示当前结点
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- Comparable AvlTree<Comparable>::findMin(AvlNode * t) const
- {
- if(t->left == NULL)
- return t->element;
- else
- return findMin(t->left);
- }
- /****************************************************************
- * 函数名称:~AvlTree()
- * 功能描写叙述: 析构函数,释放结点内存空间
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- AvlTree<Comparable>::~AvlTree()
- {
- makeEmpty();
- }
- /****************************************************************
- * 函数名称:void insert(const Comparable & x)
- * 功能描写叙述: 插入值为x的结点
- * 參数列表: x为要插入结点的值
- * 返回结果:void
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::insert(const Comparable & x)
- {
- insert(x, root);
- }
- /****************************************************************
- * 函数名称:void insert(const Comparable & x, AvlNode * t)
- * 功能描写叙述: 在结点t的后面插入值为x的结点
- * 參数列表: x为要插入结点的值
- * t为当前的结点
- * 返回结果:void
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::insert(const Comparable & x, AvlNode * & t)
- {
- if(t == NULL)//当前结点为空
- t = new AvlNode(x, NULL, NULL);
- else if(x < t->element){
- insert(x, t->left);
- if(height(t->left) - height(t->right) == 2){
- if(x < t->left->element)//单旋转。左左插入
- rotateWithLeftChild(t);
- else
- doubleWithLeftChild(t);//双旋转,左右插入
- }
- }
- else if(x > t->element){
- insert(x, t->right);
- if(height(t->right) - height(t->left) == 2){
- if(x > t->right->element)//单旋转,右右插入
- rotateWithRightChild(t);
- else
- doubleWithRightChild(t);//双旋转,右左插入
- }
- }
- //假设x的值和当前结点的值同样,则忽略。也能够向之前二叉查找树一样给每一个结点再加一个num成员变量。
- t->height = max(height(t->left), height(t->right)) + 1;//更新结点t的高度
- }
- /****************************************************************
- * 函数名称:rotateWithLeftChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行单旋转。用于左左插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::rotateWithLeftChild(AvlNode * & k2)
- {
- cout << "左单旋转" << endl;
- AvlNode * k1 = k2->left;
- k2->left = k1->right;
- k1->right = k2;
- k2->height = max(height(k2->left), height(k2->right)) + 1;
- k1->height = max(height(k1->left), k2->height) + 1;
- k2 = k1;
- }
- /****************************************************************
- * 函数名称:rotateWithRightChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行单旋转,用于左右插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::rotateWithRightChild(AvlNode * & k1)
- {
- cout << "右单旋转" << endl;
- AvlNode * k2 = k1->right;
- k1->right = k2->left;
- k2->left = k1;
- k1->height = max(height(k1->left), height(k1->right)) + 1;
- k2->height = max(height(k2->right), k1->height) + 1;
- k1 = k2;
- }
- /****************************************************************
- * 函数名称:doubleWithLeftChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行双旋转,用于左右插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::doubleWithLeftChild(AvlNode * & k3)
- {
- cout << "**********************" << endl;
- cout << "左双旋转: " << endl;
- rotateWithRightChild(k3->left);
- rotateWithLeftChild(k3);
- cout << "**********************" << endl;
- }
- /****************************************************************
- * 函数名称:doubleWithRightChild(AvlNode *t)
- * 功能描写叙述: 将当前结点进行双旋转,用于右左插入的时候
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::doubleWithRightChild(AvlNode * & k1)
- {
- cout << "**********************" << endl;
- cout << "右双旋转: " << endl;
- rotateWithLeftChild(k1->right);
- rotateWithRightChild(k1);
- cout << "**********************" << endl;
- }
- /****************************************************************
- * 函数名称:int height(AvlNode *t) const
- * 功能描写叙述: 获得当前结点t的高度
- * 參数列表: t是指向当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- int AvlTree<Comparable>::height(AvlNode * t) const
- {
- return (t == NULL) ? -1 : t->height;
- }
- /****************************************************************
- * 函数名称:biggerOrderPrintTree()
- * 功能描写叙述: 依照从大到小的顺序输出该树结点
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::biggerOrderPrintTree()
- {
- cout << "从大到小输出:";
- biggerOrderPrintTree(root);
- cout << endl;
- }
- /****************************************************************
- * 函数名称:biggerOrderPrintTree(AvlNode * t)
- * 功能描写叙述: 依照从大到小的顺序输出该树结点
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::biggerOrderPrintTree(AvlNode * t)
- {
- if(t != NULL){
- biggerOrderPrintTree(t->right);
- cout << t->element << " ";
- biggerOrderPrintTree(t->left);
- }
- }
- /****************************************************************
- * 函数名称:lessOrderPrintTree()
- * 功能描写叙述: 依照从小到大的顺序输出该树结点
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::lessOrderPrintTree()
- {
- cout << "从小到大输出:";
- lessOrderPrintTree(root);
- cout << endl;
- }
- /****************************************************************
- * 函数名称:lessOrderPrintTree()
- * 功能描写叙述: 依照从小到大的顺序输出该树结点
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::lessOrderPrintTree(AvlNode * t)
- {
- if(t != NULL){
- lessOrderPrintTree(t->left);
- cout << t->element << " ";
- lessOrderPrintTree(t->right);
- }
- }
- /****************************************************************
- * 函数名称:makeEmpty()
- * 功能描写叙述: 将该AVL平衡树清空
- * 參数列表: 无
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::makeEmpty()
- {
- makeEmpty(root);
- }
- /****************************************************************
- * 函数名称:makeEmpty(struct AvlNode * t)
- * 功能描写叙述: 释放t指针指向的结点
- * 參数列表: t 当前结点的指针
- * 返回结果:无
- *****************************************************************/
- template<typename Comparable>
- void AvlTree<Comparable>::makeEmpty(AvlNode * t)
- {
- if(t != NULL){
- makeEmpty(t->left);
- makeEmpty(t->right);
- delete t;
- }
- }
- /****************************************************************
- * 函数名称:isEmpty()
- * 功能描写叙述: 推断该树是否为空
- * 參数列表: 无
- * 返回结果:假设为空则返回true;否则返回false;
- *****************************************************************/
- template<typename Comparable>
- bool AvlTree<Comparable>::isEmpty() const
- {
- return (root == NULL) ? true : false;
- }
- //測试主函数
- int main()
- {
- vector<int> v;
- AvlTree<int> tree;
- for(int i = 0; i < 10; i++)
- v.push_back(rand() % 10);
- cout << "v: ";
- for(int i = 0; i < 10; ++i)
- cout << v[i] << " ";
- cout << endl;
- cout << "构造AVL树trre1: " << endl;
- for(int i = 0; i < 10; ++i)
- tree.insert(v[i]);
- tree.insert(13);
- tree.insert(12);
- tree.insert(11);
- tree.lessOrderPrintTree();
- tree.biggerOrderPrintTree();
- AvlTree<int> tree2;
- cout << "构造AVL树trre2: " << endl;
- for(int i = 1; i < 8; ++i)
- tree2.insert(i);
- tree2.insert(16);
- tree2.insert(15);
- tree2.lessOrderPrintTree();
- tree2.biggerOrderPrintTree();
- int min = tree2.findMin();
- cout << "min = " << min << endl;
- int max = tree2.findMax();
- cout << "max = " << max << endl;
- return 0;
- }
数据结构与算法——AVL树类的C++实现的更多相关文章
- [数据结构与算法] : AVL树
头文件 typedef int ElementType; #ifndef _AVLTREE_H_ #define _AVLTREE_H_ struct AvlNode; typedef struct ...
- 数据结构和算法(Golang实现)(28)查找算法-AVL树
AVL树 二叉查找树的树高度影响了查找的效率,需要尽量减小树的高度,AVL树正是这样的树. 一.AVL树介绍 AVL树是一棵严格自平衡的二叉查找树,1962年,发明者Adelson-Velsky和La ...
- 数据结构(三)实现AVL树
AVL树的定义 一种自平衡二叉查找树,中面向内存的数据结构. 二叉搜索树T为AVL树的满足条件为: T是空树 T若不是空树,则TL.TR都是AVL树,且|HL-HR| <= 1 (节点的左子树高 ...
- 【数据结构】平衡二叉树—AVL树
(百度百科)在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增 ...
- 数据结构与算法分析-AVL树
1.AVL树是带有平衡条件的二叉查找树. 2.AVL树的每个节点高度最多相差1. 3.AVL树实现的难点在于插入或删除操作.由于插入和删除都有可能破坏AVL树高度最多相差1的特性,所以当特性被破坏时需 ...
- 数据结构——二叉查找树、AVL树
二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...
- [算法] avl树实现
大二的时候数据结构课死活没看懂的一个东东,看了2小时,敲了2小时,调了2小时... 平衡树某一节点的左右子树高度相差大于1的时候即需要调整,调整可分为四中情况 ll,rr,lr,rl其中lr,rl是由 ...
- 数据结构与算法—Trie树
Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...
- Android版数据结构与算法(六):树与二叉树
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 之前的篇章主要讲解了数据结构中的线性结构,所谓线性结构就是数据与数据之间是一对一的关系,接下来我们就要进入非线性结构的世界了,主要是树与图,好了接 ...
随机推荐
- Python守护进程、进程互斥锁、进程间通信ICP(Queue队列)、生产者消费者模型
知识点一:守护进程 守护进程:p1.daemon=True 守护进程其实就是一个“子进程“,守护=>伴随 守护进程会伴随主进程的代码运行完毕后而死掉 进程:当父进程需要将一个任务并发出去执行,需 ...
- C语言总结(1)
1scanf( )和printf( )属于系统的函数,分别表示输入和输出. 2.所有C语言的程序只有一个main( )函数,从这里开始运行. 3.程序先执行main( ),调用scanf( ),最后输 ...
- 指定特殊的安装目录用configure进行配置
linux - Make install, but not to default directories? - Stack Overflow I want to run 'make install' ...
- 【bzoj2561】最小生成树 网络流最小割
题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...
- [BZOJ2678][Usaco2012 Open]Bookshelf
P.S. 偶然间发现可以用 markdown... [BZOJ2678][Usaco2012 Open]Bookshelf 试题描述 When Farmer John isn't milking co ...
- Java--消除重复数字后的最大值
描述: 一个长整型数字,消除重复的数字后,得到最大的一个数字. 如12341 ,消除重复的1,可得到1234或2341,取最大值2341. 42234,消除4 得到4223 或者 2234 ,再消除2 ...
- 【HDOJ5974】A Simple Math Problem(构造,解方程)
题意:给定A与B,要求构造出一组X,Y,使得X+Y=A,lcm(X,Y)=B A<=2e4,B<=1e9 思路:A的范围较小,考虑以A为突破口 枚举A的约数k,复杂度O(sqrt(A)) ...
- Java手机游戏开发简明教程 (SunJava开发者认证程序员 郎锐)
原文发布时间为:2008-07-30 -- 来源于本人的百度文章 [由搬家工具导入] Java手机游戏开发实例简明教程 (SunJava开发者认证程序员 郎锐)一、手机游戏编写基础1.手机游戏设计的基 ...
- 转 Python爬虫入门七之正则表达式
静觅 » Python爬虫入门七之正则表达式 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串 ...
- 标准C程序设计七---112
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...