#include <iostream>

using namespace std;

//AVL树的节点
template<typename T>
class TreeNode
{
public:
TreeNode() :lson(NULL), rson(NULL), freq(), hgt(){}
T data;//值
int hgt;//以这个结点为根的树的高度
int freq;//相同点的频率,我是不知道
TreeNode* lson, *rson;//左右儿子的地址
}; template<typename T>
class AVLTree
{//AVLTree的类属性和方法声明
private:
TreeNode<T>*root;//根节点
void insertpri(TreeNode<T>*&node, T x);//插入
TreeNode<T>* findpri(TreeNode<T>* node, T x);//查找
void traversalpri(TreeNode<T>* node);//遍历
void delpri(TreeNode<T>* &node, T x);//删除
int height(TreeNode<T>* node);//辅助操作:高度
void singLeft(TreeNode<T>* &k2);//左左操作
void singRight(TreeNode<T>* &k2);//右右操作
void doubleLeft(TreeNode<T>* &k3);//左右操作
void doubleRight(TreeNode<T>* &k3);//右左操作
int max(int cmpa, int cmpb);
public:
AVLTree() :root(NULL){};
void insert(T x);//插入接口
void del(T x);//删除接口
TreeNode<T>* find(T x);//查找接口
void traversal();//遍历接口
}; //辅助操作:高度
template<typename T>
int AVLTree<T>::height(TreeNode<T>* node)
{
if (node!=NULL)
return node->hgt;
return -;
} //辅助操作:比较高度
template<typename T>
int AVLTree<T>::max(int cmpa, int cmpb)
{
return cmpa > cmpb ? cmpa : cmpb;
} template<typename T>
void AVLTree<T>::singLeft(TreeNode<T>* &k2)
{//左左情况下旋转
TreeNode<T>* k1;
k1 = k2->lson;
k2->lson = k1->rson;
k1->rson = k2;
k2 = k1;
k2->hgt = max(height(k2->lson), height(k2->rson))+;
k1->hgt = max(height(k1->lson), height(k1->rson))+;
} template<typename T>
void AVLTree<T>::singRight(TreeNode<T>* &k2)
{//左左情况下旋转
TreeNode<T>* k1;
k1 = k2->rson;
k2->rson = k1->lson;
k1->lson = k2;
k2 = k1;
k2->hgt = max(height(k2->lson), height(k2->rson))+;
k1->hgt = max(height(k1->lson), height(k1->rson))+;
} template<typename T>
void AVLTree<T>::doubleLeft(TreeNode<T>* &k3)
{//左右的情况
singRight(k3->lson);
singLeft(k3);
} //右左的情况
template<typename T>
void AVLTree<T>::doubleRight(TreeNode<T>* &k3)
{
singLeft(k3->rson);
singRight(k3);
} //插入
template<typename T>
void AVLTree<T>::insertpri(TreeNode<T>* &node, T x)
{
if (node == NULL)
{
node = new TreeNode<T>();
node->data = x;
return;
}
if (node->data>x)
{
insertpri(node->lson, x);//递归插入
//插入后自我调整
if ( == height(node->lson) - height(node->rson))
if (node->lson->data < x)
doubleRight(node);
else
singLeft(node);
}
else if (node->data < x)
{
insertpri(node->rson, x);
if ( == height(node->rson) - height(node->lson))
if (node->rson->data < x)
singRight(node);
else
doubleRight(node);
}
else ++(node->freq);
//取新的高度值,后面的+1很重要,作者都忘记了加
node->hgt = max(height(node->lson), height(node->rson)) + ;
} //插入接口
template<typename T>
void AVLTree<T>::insert(T x)
{
insertpri(root, x);
} //查找
template<typename T>
TreeNode<T>* AVLTree<T>::findpri(TreeNode<T>* node, T x)
{
if (node == NULL)
return NULL;
if (node->data > x)
return findpri(node->lson, x);
else if (node->data < x)
return findpri(node->rson, x);
else return node;
} //查找
template<typename T>
TreeNode<T>* AVLTree<T>::find(T x)
{
findpri(root, x);
} //删除
template<typename T>
void AVLTree<T>::delpri(TreeNode<T>* &node,T x)
{
if (node == NULL)
return;
if (x < node->data)
{
delpri(node->lson, x);
//删除后的调整
if ( == height(node->rson) - height(node->lson))
if (node->rson->lson&&height(node->rson->lson) > height(node->rson->rson))
doubleRight(node);
else
singRight(node);
}
else if (x > node->data)
{
delpri(node->rson, x);
if ( == height(node->lson) - height(node->rson))
if (node->lson->rson&&height(node->lson->rson) > height(node->lson->lson))
doubleLeft(node);
else
singLeft(node);
}
else//找到后的操作
{//先是有两个儿子的情况
if (node->lson&&node->rson)
{
TreeNode<T>* t = node->lson;
for (; t->rson; t = t->rson);
node->data = t->data;
node->freq = t->freq;
//递归到一个儿子或没有儿子的情况
delpri(node->lson, t->data);
if ( == height(node->rson) - height(node->lson))
{//下面的if自己不会写
if (node->rson->lson&&height(node->rson->lson) > height(node->rson->rson))
doubleRight(node);
else
singRight(node);
}
}
else
{
TreeNode<T>* t = node;
if (node->lson == NULL)
node = node->rson;
else if (node->rson == NULL)
node = node->lson;
delete(t);
t = NULL;
}
}
if (node == NULL)return;//表示只有根节点,删了之后就没有了
node->hgt = max(height(node->lson), height(node->rson));
return;
} template<typename T>
void AVLTree<T>::del(T x)
{
delpri(root, x);
} //中序遍历函数
template<class T>
void AVLTree<T>::traversalpri(TreeNode<T>* node)
{
if (node == NULL) return;
traversalpri(node->lson);//先遍历左子树
cout << node->data << " ";//输出根节点
traversalpri(node->rson);//再遍历右子树
}
//中序遍历接口
template<class T>
void AVLTree<T>::traversal()
{
traversalpri(root);
} int main()
{
AVLTree<int> t;
t.insert();
t.insert();
t.insert();
t.insert();
t.insert();
t.insert();
t.del();
t.insert();
t.traversal();
}

AVL树相关操作的更多相关文章

  1. AVL树插入操作实现

    为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...

  2. avl树的操作证明

    以下用大O表示节点,ABC表示三个集合. 仅分析左子树的情况,因为对称,右子树的情况一样. 插入节点前 O /     \ O        A   /    \ B       C 插入节点后: O ...

  3. 数据结构树之AVL树(平衡二叉树)

    一 什么是AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节 ...

  4. 图解数据结构树之AVL树

    AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节点的两个子 ...

  5. AVL树Python实现

    # coding=utf-8 # AVL树Python实现 def get_height(node): return node.height if node else -1 def tree_mini ...

  6. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  7. AVL树(平衡二叉树)

    定义及性质 AVL树:AVL树是一颗自平衡的二叉搜索树. AVL树具有以下性质: 根的左右子树的高度只差的绝对值不能超过1 根的左右子树都是 平衡二叉树(AVL树) 百度百科: 平衡二叉搜索树(Sel ...

  8. AVL树(查找、插入、删除)——C语言

    AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树(AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Land ...

  9. 深入理解索引和AVL树、B-树、B+树的关系

    目录 什么是索引 索引的分类 索引和AVL树.B-树.B+树的关系 AVL树.红黑树 B-树 B+树 SQL和NoSQL索引 什么是索引 索引时数据库的一种数据结构,数据库与索引的关系可以看作书籍和目 ...

随机推荐

  1. REDIS学习(1)环境搭建

    1.下载 稳定版本的.tar.gz 包,解压到/usr/local/src/. 2 .cd 到文件夹下,不需要 configure 直接 make编译 ,成功之后,cd /usr/local/redi ...

  2. 为Linux服务器伪装上Windows系统假象

    网络上的计算机很容易被黑客利用工具或其它手段进行扫描,以寻找系统中的漏洞,然后再针对漏洞进行攻击. 通过伪装Linux系统,给黑客设置系统假象,可以加大黑客对系统的分析难度,引诱他们步入歧途,从而进一 ...

  3. python命令行运行在win和Linux系统的不同

    今天,在完成一个小的python习题,习题的主要内容是读取一个帮助模块,并保存到本地文件. 知道是用pydoc进行模块的读取,但是在windows系统下,调用os模块之后,结果总是为空. 核心语句: ...

  4. Lua----注意事项

    前言:Lua相对一般的语言相对简单,有c基础看一遍就差不多了.一般的代码都能够看懂.但是Lua也有一些自己的特点,区别与其他语言,这里需要注意一下. 1.数组下标 在Lua中数组下标是从1开始计数的. ...

  5. ioctl函数,可以获取ip地址,修改ip地址,网卡地址等

    部分转自http://www.cnblogs.com/zht-blog/p/4025903.html #include <sys/types.h>#include <sys/sock ...

  6. 从汇编来看c语言之指针

    一.基础研究 将下面的程序编译连接,用debug加载: 首先执行第一条语句: 发现p=(unsigned char *)0x1000;在这里是把1000赋给一个偏移地址为01af.大小为两字节的内存空 ...

  7. Large sum

    聪明的办法是想:求前10位,那只要前8位加起来,进2位就OK. 本的办法,就是真的加起来,截前面10位.如我. numList = str.split() sum = 0 for i in range ...

  8. ubuntu的web开发环境搭建

    为了保持mac的干净整洁,决定用PD搭建一条web开发环境,记下整个过程. ubuntu 首先是操作系统,本着习惯就好的原则,选用了Ubuntu server 12.04.4版.系统的安装很简单,ht ...

  9. 将 Web 应用性能提高十倍的10条建议

    提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料).这个时刻在线的超连接世界意味着用户对其的期望值也处于历史上 ...

  10. AngularJS和ReactJS对比

    Angular的特点: 优势: AngularJS是一套完整的框架,angular有自带的数据绑定.render渲染.angularUI库,过滤器,$filter,$directive(模板),$se ...