手写AVL 树(下)
上一篇 手写AVL树上实现了AVL树的插入和查询
上代码:
头文件:AVL.h
#include <iostream>
template<typename T1,typename T2> struct Tree
{
Tree* leftChild;
Tree* rightChild;
Tree* father;
T1 key;
T2 value;
int leftHeight;
int rightHeight;
};
template<typename T1,typename T2> class AVL
{
public:
AVL();
void Put(T1 key,T2 value);
void Delete(T1 key);
T2 Get(T1 key);
private:
Tree<T1,T2>* tree;
void ReComputeRightHeight(Tree<T1,T2>*& root);
void ReComputeLeftHeight(Tree<T1,T2>*& root);
void LeftSpin(Tree<T1,T2>*& root);
void RightSpin(Tree<T1,T2>*& root);
void LeftRightSpin(Tree<T1,T2>*& root);
void RightLeftSpin(Tree<T1,T2>*& root);
void Rebalance(Tree<T1,T2>*& root);
void Insert(Tree<T1,T2>*& father,Tree<T1,T2>*& root,T1 key,T2 value);
void DeleteNode(Tree<T1,T2>*& root,int tag);
void LeftScoper(Tree<T1,T2>*& source,Tree<T1,T2>*& root,int tag);
void RightScoper(Tree<T1,T2>*& source,Tree<T1,T2>*& root,int tag);
void Remove(Tree<T1,T2>*& root,T1 key,int tag);
T2 Find(Tree<T1,T2>* root,T1 key);
};
源文件:AVL.cpp
#include "AVL.h"
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
template<class T1,class T2>
AVL<T1,T2>::AVL()
{
tree = NULL;
}
template<class T1,class T2>
void AVL<T1,T2>::ReComputeRightHeight(Tree<T1,T2>*& root)
{
if(root->rightChild==NULL)
root->rightHeight = 0;
else
root->rightHeight = max(root->rightChild->leftHight,root->rightChild->rightHeight)+1;
}
template<class T1,class T2>
void AVL<T1,T2>::ReComputeLeftHeight(Tree<T1,T2>*& root)
{
if(root->leftChild==NULL)
root->leftHeight = 0;
else
root->leftHeight = max(root->leftChild->leftHight,root->leftChild->rightHeight)+1;
}
template<class T1,class T2>
void AVL<T1,T2>::LeftSpin(Tree<T1,T2>*& root)
{
if(root->rightChild==NULL) return;
Tree<T1,T2>* father = root->father;
Tree<T1,T2>* temp = root;
Tree<T1,T2>* temp2 = root->rightChild->leftChild;
root = temp->rightChild;
root->leftChild = temp;
root->father = father;
temp->father = root;
temp->rightChild = temp2;
if(temp2!=NULL)
temp2->father = temp;
ReComputeRightHeight(root->leftChild);
ReComputeLeftHeight(root);
}
template<class T1,class T2>
void AVL<T1,T2>::RightSpin(Tree<T1,T2>*& root)
{
if(root->leftChild==NULL) return;
Tree<T1,T2>* father = root->father;
Tree<T1,T2>* temp = root;
Tree<T1,T2>* temp2 = root->leftChild->rightChild;
root = temp->leftChild;
root->rightChild = temp;
root->father = father;
temp->father = root;
temp->leftChild = temp2;
if(temp2!=NULL)
temp2->father = temp;
ReComputeLeftHeight(root->rightChild);
ReComputeRightHeight(root);
}
template<class T1,class T2>
void AVL<T1,T2>::LeftRightSpin(Tree<T1,T2>*& root)
{
LeftSpin(root->leftChild);
RightSpin(root);
}
template<class T1,class T2>
void AVL<T1,T2>::RightLeftSpin(Tree<T1,T2>*& root)
{
RightSpin(root->rightChild);
LeftSpin(root);
}
template<class T1,class T2>
void AVL<T1,T2>::Rebalance(Tree<T1,T2>*& root)
{
if(root->leftHeight > root->rightHeight+1)
{
if(root->leftChild->leftHeight < root->leftChild->rightHeight)
{
LeftRightSpin(root);
}
else
RightSpin(root);
}
else if(root->leftHeight<root->rightHeight-1)
{
if(root->rightChild->rightHeight<root->rightChild->leftHeight)
{
RightLeftSpin(root);
}
else
LeftSpin(root);
}
}
template<class T1,class T2>
void AVL<T1,T2>::Insert(Tree<T1,T2>*& father, Tree<T1,T2>*& root, T1 key,T2 value)
{
if(root==NULL)
{
root = new Tree<T1,T2>;
root->leftChild=NULL;
root->rightChild=NULL;
root->key = key;
root->value = value;
root->leftHeight = 0;
root->rightHeight = 0;
root->father = father;
return;
}
if(key == root->key)
{
root->value = value;
return;
}
if(key < root->key)
{
Insert(root,root->leftChild,key,value);
ReComputeLeftHeight(root);
Rebalance(root);
}
else if(key > root->key){
Insert(root,root->rightChild,key,value);
ReComputeRightHeight(root);
Rebalance(root);
}
}
template<class T1,class T2>
void AVL<T1,T2>::Put(T1 key,T2 value)
{
Insert(tree,tree,value, value);
}
template<class T1,class T2>
T2 AVL<T1,T2>::Find(Tree<T1,T2>* root,T1 key)
{
if(root==NULL)
return NULL;
if(key<root->key&&root->leftChild!=NULL)
{
return Get(root->leftChild,key);
}
if(key>root->key&&root->rightChild!=NULL)
{
return Get(root->rightChild,key);
}
if(key==root->key)
{
return root->value;
}
return NULL;
}
template<class T1,class T2>
T2 AVL<T1,T2>::Get(T1 key)
{
Find(tree,key);
}
template<class T1,class T2>
void AVL<T1,T2>::DeleteNode(Tree<T1,T2>*& root,int tag)
{
if(root->leftChild!=NULL)
{
if(tag==0)
{
if(root->father == root)
root->leftChild = NULL;
else
{
root->father->leftChild = root->leftChild;
root->father = root->father->father;
}
}
else if(tag==1)
{
if(root->father == root)
root->rightChild = NULL;
else
{
root->father->rightChild = root->leftChild;
root->father = root->father->father;
}
}
}
else if(root->rightChild!=NULL)
{
if(tag==0)
{
if(root->father == root)
{
root->leftChild = NULL;
}
else
{
root->father->leftChild = root->rightChild;
root->father = root->father->father;
}
}
else if(tag==1)
{
if(root->father == root)
{
root->rightChild = NULL;
}
else
{
root->father->rightChild = root->rightChild;
root->father = root->father->father;
}
}
}
else
{
if(root->father == root)
root = NULL;
else
{
if(tag==0)
root->father->leftChild=NULL;
else if(tag==1)
root->father->rightChild=NULL;
}
}
}
template<class T1,class T2>
void AVL<T1,T2>::LeftScoper(Tree<T1,T2>*& source, Tree<T1,T2>*& root,int tag)
{
if(root->leftChild!=NULL)
{
LeftScoper(source,root->leftChild,0);
ReComputeLeftHeight(root);
Rebalance(root);
}
else
{
source->key = root->key;
source->value = root->value;
DeleteNode(root,tag);
}
}
template<class T1,class T2>
void AVL<T1,T2>::RightScoper(Tree<T1,T2>*& source, Tree<T1,T2>*& root,int tag)
{
if(root->rightChild!=NULL)
{
RightScoper(source,root->rightChild,1);
ReComputeRightHeight(root);
Rebalance(root);
}
else
{
source->key = root->key;
source->value = root->value;
DeleteNode(root, tag);
}
}
template<class T1,class T2>
void AVL<T1,T2>::Remove(Tree<T1,T2>*& root,T1 key,int tag)
{
if(root==NULL)
return;
if(key == root->key)
{
if(root->leftChild==NULL&&root->rightChild==NULL)
{
DeleteNode(root,tag);
}
else
{
if(root->rightChild!=NULL)
{
LeftScoper(root,root->rightChild,1);
ReComputeRightHeight(root);
Rebalance(root);
}
else if(root->leftChild!=NULL)
{
RightScoper(root,root->leftChild,0);
ReComputeLeftHeight(root);
Rebalance(root);
}
}
return;
}
if(key<root->key)
{
Remove(root->leftChild,key,0);
ReComputeLeftHeight(root);
Rebalance(root);
}
if(key>root->key)
{
Remove(root->rightChild,key,1);
ReComputeRightHeight(root);
Rebalance(root);
}
}
template<class T1,class T2>
void AVL<T1,T2>::Delete(T1 key)
{
remove(tree,key,0);
}
手写AVL 树(下)的更多相关文章
- 手写AVL 树(上)
平衡二叉树 左旋,右旋,左右旋,右左旋 具体原理就不说了,网上教程很多.这里只实现了建树的过程,没有实现删除节点的操作. 下一篇会实现删除节点的操作. // // main.cpp // AVL // ...
- 手写AVL平衡二叉搜索树
手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...
- vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件
vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...
- AVL树的理解及自写AVL树
AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下都是O(log n).增加和删除可能需要通过一次或多 ...
- 手写的select 下拉菜单
我们在进行表单设计时,可能要用到select下拉选项控件,遗憾的是,IE浏览器默认的select控件外观非常丑陋,而且不能用样式来控制,不能在选项中添加图片等信息.今天我将通过实例来讲解如何用CSS和 ...
- 一步一步写平衡二叉树(AVL树)
平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...
- 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...
- 待实践二:MVC3下的3种验证 (1)前台 jquery validate验证 (2)MVC实体验证 (3)EF生成的/自己手写的 自定义实体校验(伙伴类+元素据共享)
MVC3下的3种验证 (1):前台Jquery Validate脚本验证 引入脚本 <script src="../js/jquery.js" type="text ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(下)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...
随机推荐
- AC自动机算法详解 (转载)
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...
- String.intern() 方法__jdk1.6与jdk1.7/jdk1.8的不同
1.为什么要使用intern()方法 intern方法设计的初衷是为了重用string对象,节省内存 用代码实例验证下 public class StringInternTest { static f ...
- L1-Day3
L1-Day31.太阳从西边落下. [我的翻译]The sun falls in the west. [标准答案]The sun sets in the west. [对比分析]落下fall与set的 ...
- 集合-Comparator和Comparable
文章内容参考博客:https://www.cnblogs.com/xujian2014/p/5215082.html 1.Comparable Comparable是排序接口,当一个类实现了Compa ...
- Python 概念小屋
 Python 中的 if __name__ == '__main__' 该如何理解 python多进程的理解 multiprocessing Process join run
- linux select 与 阻塞( blocking ) 及非阻塞 (non blocking)实现io多路复用的示例【转】
转自:https://www.cnblogs.com/welhzh/p/4950341.html 除了自己实现之外,还有个c语言写的基于事件的开源网络库:libevent http://www.cnb ...
- MS SQL Server 查询元数据
use test -- 查询数据库中所有的表和架构名称select SCHEMA_NAME(schema_id) as table_schema_name, name as table_name fr ...
- cocos2dx-lua 圆角矩形 圆角图片 drawNode
使用的官方类是:drawNode 函数是:drawNode:drawPolygon() C++函数的参数说明: //画多边形,verts为点集,count为点数,fillColor为填充颜色,bord ...
- 初识C语言(一)
C语言的结构体 一个C程序就是由多个头文件和函数组成 #include<stdio.h> /* 包含头文件*/ int main() { printf('"hello world ...
- java 查找类的所有子类
package _02; import java.io.File; import java.net.URL; public class MainTest_FindAllSubClass { publi ...