手写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 ...
随机推荐
- 1120 机器人走方格 V3(组合数)
题目实际上是求catalan数的,Catalan[n] = C(2*n,n) / (n+1) = C(2*n,n) % mod * inv[n+1],inv[n+1]为n+1的逆元,根据费马小定理,可 ...
- 杨辉三角(用for循环)
public class Test413__________________ { public static void main(String[] args) { int rows = 10; for ...
- Lua中的语句
[赋值] 赋值的基本含义是修改一个变量或一个table中字段的值,这个和其它语言没有多少区别,但是对于Lua,有一个特性,它允许“多重赋值”,也就是一下子将多个值赋予多个变量,例如以下代码: , pr ...
- Coverity代码扫描工具
1.说明:Coverity代码扫描工具可以扫描java,C/C++等语言,可以和jenkins联动,不过就是要收钱,jenkins上的插件可以用,免费的,适用于小的java项目 2.这是Coverit ...
- [转] vue之computed和watch
计算属性 computed 侦听器or观察者 watch 一直以来对computed和watch一知半解,用的时候就迷迷糊糊的,今天仔细看了看文档,突然茅塞顿开,原来就是这么简单啊: computed ...
- 不装插件,查看.rp文件
AxShare国内平台地址:http://share.axure.org临时急用可以使用公用帐户.用户名:axure@webppd.com,密码:webppd123 上传.rp文件,点击 url 地址 ...
- [转]IntelliJ IDEA 使用spring-boot-devtools热部署无效解决办法
来源:https://www.jianshu.com/p/4d8aa6dfd103 相信大部分使用IntelliJ IDEA的同学都会遇到这个问题,即使项目使用了spring-boot-devtool ...
- MD5加密工具类
简单的md5加密: package com.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithm ...
- 001.Ansible部署RHCS存储集群
一 前期准备 1.1 前置条件 至少有三个不同的主机运行monitor (MON)节点: 至少三个直接存储(非外部SAN硬件)的OSD节点主: 至少两个不同的manager (MGR)节点: 如果使用 ...
- Selenium2+python自动化45-18种定位方法(find_elements)
前言 江湖传言,武林中流传八种定位,其中xpath是宝刀屠龙,css是倚天剑. 除了这八种,其实还有十种定位方法,眼看就快失传了,今天小编让失传已久的定位方法重出江湖! 一.十八种定位方法 前八种是大 ...