AVL平衡树(非指针实现)
看了网上三四篇博客,学习了AVL树维护平衡的方式。但感觉他们给出的代码都有一点瑕疵或者遗漏,懂得了思想之后,花了一些时间把他们几篇的长处结合起来,没有使用指针,实现了一下。每个小逻辑功能都抽象成了函数,应该比较好理解,代码逻辑看起来也比较清晰。下面给出主要的功能插入和删除。至于其他一些没有动到树结构的操作,如查询,求前驱后继等,同其他BST,没有什么特别。
这里顺带一提,下面的代码中,没有维护子树size,如果要求第K小或者名次,可以在upd函数等处添加有关size的维护,之后便可以支持相关查询了。
#include<iostream>
#include<algorithm>
#define de(x) cout<<#x<<" = "<<x<<endl
using namespace std;
const int maxn=1e5+10;
struct AVL
{
int key,h,lc,rc;
}tree[maxn];
int id,root;
inline int newNode(int k,int l,int r)
{
tree[++id].key=k;
tree[id].lc=l;
tree[id].rc=r;
tree[id].h=0;
return id;
}
inline int height(int id)
{
return id ? tree[id].h : 0;
}
inline void upd(int id)
{
if (!id)
return;
int lh=height(tree[id].lc), rh=height(tree[id].rc);
tree[id].h=max(lh, rh)+1;
}
inline int rightRotate(int id)
{
int lc=tree[id].lc;
tree[id].lc=tree[lc].rc;
tree[lc].rc=id;
upd(id);
upd(lc);
return lc;
}
inline int leftRotate(int id)
{
int rc=tree[id].rc;
tree[id].rc=tree[rc].lc;
tree[rc].lc=id;
upd(id);
upd(rc);
return rc;
}
inline int lrRotate(int id)
{
tree[id].lc=leftRotate(tree[id].lc);
return rightRotate(id);
}
inline int rlRotate(int id)
{
tree[id].rc=rightRotate(tree[id].rc);
return leftRotate(id);
}
inline int balance(int id)
{
if (height(tree[id].lc)-height(tree[id].rc) > 1)
{
int lc=tree[id].lc;
if (height(tree[lc].lc) > height(tree[lc].rc))
return rightRotate(id);
else
return lrRotate(id);
}
else if (height(tree[id].rc)-height(tree[id].lc) > 1)
{
int rc=tree[id].rc;
if (height(tree[rc].lc) < height(tree[rc].rc))
return leftRotate(id);
else
return rlRotate(id);
}
return id;
}
int getMax(int id)
{
if (!id)
return 0;
while (tree[id].rc)
id=tree[id].rc;
return id;
}
int getMin(int id)
{
if (!id)
return 0;
while (tree[id].lc)
id=tree[id].lc;
return id;
}
void insert(int& rt, int v)
{
if (!rt)
rt=newNode(v,0,0);
else if (v < tree[rt].key)
insert(tree[rt].lc, v);
else if (v > tree[rt].key)
insert(tree[rt].rc, v);
rt=balance(rt);
upd(rt);
return;
}
void del(int& rt, int v)
{
if (!rt)
return;
if (v < tree[rt].key)
del(tree[rt].lc, v);
else if (v > tree[rt].key)
del(tree[rt].rc, v);
else
{
if (tree[rt].lc&&tree[rt].rc)
{
if (height(tree[rt].lc) > height(tree[rt].rc))
{
int maxId=getMax(tree[rt].lc);
tree[rt].key=tree[maxId].key;
del(tree[rt].lc, tree[maxId].key);
}
else
{
int minId=getMin(tree[rt].rc);
tree[rt].key=tree[minId].key;
del(tree[rt].rc, tree[minId].key);
}
}
else
rt=tree[rt].lc ? tree[rt].lc : tree[rt].rc;
}
rt=balance(rt);
upd(rt);
}
AVL平衡树(非指针实现)的更多相关文章
- 实现Avl平衡树
实现Avl平衡树 一.介绍 AVL树是一种自平衡的二叉搜索树,它由Adelson-Velskii和 Landis于1962年发表在论文<An algorithm for the organi ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- Python与数据结构[3] -> 树/Tree[2] -> AVL 平衡树和树旋转的 Python 实现
AVL 平衡树和树旋转 目录 AVL平衡二叉树 树旋转 代码实现 1 AVL平衡二叉树 AVL(Adelson-Velskii & Landis)树是一种带有平衡条件的二叉树,一棵AVL树其实 ...
- 数据结构学习-AVL平衡树
环境:C++ 11 + win10 IDE:Clion 2018.3 AVL平衡树是在BST二叉查找树的基础上添加了平衡机制. 我们把平衡的BST认为是任一节点的左子树和右子树的高度差为-1,0,1中 ...
- AVL平衡树的插入例程
/* **AVL平衡树插入例程 **2014-5-30 11:44:50 */ avlTree insert(elementType X, avlTree T){ if(T == NULL){ T = ...
- 【转】 史上最详尽的平衡树(splay)讲解与模板(非指针版spaly)
ORZ原创Clove学姐: 变量声明:f[i]表示i的父结点,ch[i][0]表示i的左儿子,ch[i][1]表示i的右儿子,key[i]表示i的关键字(即结点i代表的那个数字),cnt[i]表示i结 ...
- AVL 平衡树
AVL是一种平衡二叉树,它通过对二叉搜索树中的节点进行旋转使得二叉搜索树达到平衡.AVL在所有的平衡二叉搜索树中具有最高的平衡性. 定义 平衡二叉树或者为空树或者为满足如下性质的二叉搜索树: 左右子树 ...
- 伸展树Splay【非指针版】
·伸展树有以下基本操作(基于一道强大模板题:codevs维护队列): a[]读入的数组;id[]表示当前数组中的元素在树中节点的临时标号;fa[]当前节点的父节点的编号;c[][]类似于Trie,就是 ...
- BZOJ3224普通平衡树——非旋转treap
题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...
随机推荐
- hdu 1113 简单字符处理问题
#include <map> #include <cstdio> #include <iostream> #include <string> #incl ...
- C#进阶之WebAPI(三)
今天复习一下WebAPI的路由知识: 首先分析一下MVC路由和WebAPI路由的区别: 在mvc里,默认的路由机制是通过URL路径去匹配控制器和Action方法的,在mvc中的默认路由定义在App_S ...
- 13 Msql之四种事务隔离界别
一.事务的基本要素 1.原子性:事务开始后的所有操作,要么全部做完,要么全部不做,不能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没发生一样.也就是说事务是一个不可分割 ...
- vue中使用svg字体图标
1.在src/ 下面新建目录icons,里面新建文件夹svg,和文件index.js .svg用于存放从iconfont下载下来的svg格式的图标,index.js用于引入使用到svg文件和对应的组件 ...
- vue项目之购物车
简单的完成一个购物车项目,满足基本功能 安装创建好项目以后需要引入安装elementui和vuex 项目目录如下:(home.vue为主页面) ### ~home.vue <template&g ...
- css样式背景图片设置缩放
一.背景颜色图片平铺 background-color 背景颜色 background-image 背景图片地址 background-repeat 是否平铺 默认是平铺 background-pos ...
- 浅谈String、StringBuffer与StringBuilder
浅谈String.StringBuffer与StringBuilder 先详细介绍一下String.StringBuffer与StringBuilder String: 官方对String的说明: ...
- Jenkins服务器安装与配置
Jenkins是一个非常出色的持续集成服务器,本文主要介绍在CentOS系统中Jenkins的基本安装配置方法,供参考. 一. 软件包: 1. 下载apache-maven-2.2.1-bin.tar ...
- STM32唯一ID(Unique Device ID)的读取方法
每一个STM32微控制器都自带一个96位的唯一ID,也就是Unique Device ID或称为UID,这个唯一ID在任何情况下都是唯一的且不允许修改. 在开发过程中,可能需要用到这个UID,比 ...
- PAT Basic 1085 PAT单位排行 (25 分)
每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜.本题就请你实现这个功能. 输入格式: 输入第一行给出一个正整数 N(≤),即考生人数.随后 N 行,每行按下列格式给出一个考生的信息: 准 ...