手写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 ...
随机推荐
- 移动端控制视频点击播放点击下一个视频时自动停止播放&监听滑动溢出屏幕高度时停止播放
直接上代码js部分: <script type="text/javascript"> var go;//记录video播放器位置 var video=document. ...
- Notepad++崩溃后文件内容找不到问题
也许是因为Ctrl + s 摁太多太频繁,一不小心Notepad++崩溃了 重启后发现原来的文件还在,但是文件内容全部都被清空了 我没有手动备份这个文件, 如何找回??? 点击设置,首选项,里面有个备 ...
- ch03 课下作业——缓冲区溢出漏洞实验
一.实验简介: 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭 ...
- DeepLearning.ai学习笔记(五)序列模型 -- week2 序列模型和注意力机制
一.基础模型 假设要翻译下面这句话: "简将要在9月访问中国" 正确的翻译结果应该是: "Jane is visiting China in September" ...
- 3D Slicer中文教程(三)—数据加载及保存方式
1.打开数据与保存数据 (1)打开数据 ——可以将数据拖拽到3D Slicer应用窗口或者从菜单栏工具栏打开. ——多种方式加载大量数据. 有关DICOM数据,请参阅DICOM模块文档. 对于几乎所有 ...
- 1.2低级线程处理API
并行扩展库相当有用,因为它允许使用更高级的抽象——任务,而不必直接和线程打交道.但有的时候,要处理的代码是在TPL和PLINQ问世(.NET4.0)之前写的.也有可能某个编程问题不能直接使用它们解决, ...
- linux ps top 命令 VSZ,RSS,TTY,STAT, VIRT,RES,SHR,DATA的含义
VIRT:virtual memory usage 虚拟内存1.进程“需要的”虚拟内存大小,包括进程使用的库.代码.数据等2.假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而 ...
- Java是解释型还是编译型语言?
有人说Java是编译型的.因为所有的Java代码都是要编译的,.java不经过编译就无法执行. 也有人说Java是解释型的.因为java代码编译后不能直接运行,它是解释运行在JVM上的,所以它是解释型 ...
- 为何学习matplotlib-【老鱼学matplotlib】
这次老鱼开始学习matplotlib了. 在上个pandas最后一篇博文中,我们已经看到了用matplotlib进行绘图的功能,这次更加系统性地学习一下关于matplotlib的功能. matlab由 ...
- Android+openCV 动态人脸检测
动态人脸检测前提是需要打开摄像头. 网上看了很多教程,我知道的有两种方式打开摄像头: JavaCameraView mCameraView = new JavaCameraView(this, -1) ...