手写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 ...
随机推荐
- 消除导入MNIST数据集发出的警告信息
原本导入数据集你仅需这样: # Import MNIST data from tensorflow.examples.tutorials.mnist import input_data mnist = ...
- C#学习笔记-域用户认证(一)
public Boolean ValidateDomainUser(string Domain, string UserName, string Password) { DirectoryEntry ...
- docker时间和本地时间不一致的问题
前言: 在本地执行date 和登录docker后的date显示的时间不一致,差一天多,不是8个小时 参考:戳这儿 先重启,查看后发现差8个小时 用里面cp localtime 再重启还是差8个小时 试 ...
- Revit二次开发之获得项目族预览图
using Autodesk.Revit.UI; using Autodesk.Revit.DB; using Autodesk.Revit.Attributes; using System.Wind ...
- Lua中__index和__newindex实践
[具有默认值的table] 我们都知道,table中的任何字段的默认值都是nil,但是通过元表,我们可以很容易的修改这一规定,代码如下: function setDefault(tb, default ...
- [ZJOI2008]树的统计-树链剖分
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; #define mid ((l+r)>> ...
- Mysql --库和表的操作
库的增删改查 系统数据库 创建数据库 数据库的相关操作 表的操作 存储引擎介绍(有点多 很啰唆) 表的介绍 表的操作 一.系统数据库 查看系统库: show databases; nformation ...
- 【原创】大叔经验分享(14)spark on yarn提交任务到集群后spark-submit进程一直等待
spark on yarn通过--deploy-mode cluster提交任务之后,应用已经在yarn上执行了,但是spark-submit提交进程还在,直到应用执行结束,提交进程才会退出,有时这会 ...
- activiti 涉及的内容
1 JAVA 委派模式(Delegate) https://blog.csdn.net/mayaofr/article/details/52082665 2 Activiti中的activiti:ex ...
- iOS rebuild from bitcode对ipa大小的影响
https://developer.apple.com/library/content/technotes/tn2432/_index.html 为了测试一下rebuild from bitcode的 ...