手写一个节点大小平衡树(SBT)模板,留着用
看了一下午,感觉有了些了解。应该没有错,有错希望斧正,感谢
#include<stdio.h>
#include<string.h>
struct s
{
int key,left,right,size;
}tree[10010];
int top;
void left_rot(int &x)// 左旋
{
int y=tree[x].right;
tree[x].right=tree[y].left;
tree[y].left=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
x=y;
}
void right_rot(int &x)//右旋
{
int y=tree[x].left;
tree[x].left=tree[y].right;
tree[y].right=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
x=y;
}
void maintain(int &x,bool flag)//维护SBT状态
{
if(flag==false)//左边
{
if(tree[tree[tree[x].left].left].size>tree[tree[x].right].size)//左孩子的左孩子大于右孩子
right_rot(x);
else
if(tree[tree[tree[x].left].right].size>tree[tree[x].right].size)//左孩子的右孩子大于右孩子
{
left_rot(tree[x].left);
right_rot(x);
}
else
return;
}
else//右边
{
if(tree[tree[tree[x].right].right].size>tree[tree[x].left].size)//右孩子的右孩子大于左孩子
left_rot(x);
else
if(tree[tree[tree[x].right].left].size>tree[tree[x].left].size)//右孩子的左孩子大于左孩子
{
right_rot(tree[x].right);
left_rot(x);
}
else
return;
}
maintain(tree[x].left,false);
maintain(tree[x].right,true);
maintain(x,true);
maintain(x,false);
}
void insert(int &x,int key)//插入
{
if(x==0)
{
x=++top;
tree[x].left=0;
tree[x].right=0;
tree[x].size=1;
tree[x].key=key;
}
else
{
tree[x].size++;
if(key<tree[x].key)
insert(tree[x].left,key);
else
insert(tree[x].right,key);//同样元素可插右子树
maintain(x,key>=tree[x].key);
}
}
int remove(int &x,int key)//利用后继删除
{
tree[x].size--;
if(key>tree[x].key)
remove(tree[x].right,key);
else
if(key<tree[x].key)
remove(tree[x].left,key);
else
if(tree[x].left!=0&&tree[x].right==0)//有左子树,无右子树
{
int temp=x;
x=tree[x].left;
return temp;
}
else
if(!tree[x].left&&tree[x].right!=0)//有右子树,无左子树
{
int temp=x;
x=tree[x].right;
return temp;
}
else
if(!tree[x].left&&!tree[x].right)//无左右子树
{
int temp=x;
x=0;
return temp;
}
else//左右子树都有
{
int temp=tree[x].right;
while(tree[temp].left)
temp=tree[temp].left;
tree[x].key=tree[temp].key;
remove(tree[x].right,tree[temp].key);
}
}
int getmin(int x)//求最小值
{
while(tree[x].left)
x=tree[x].left;
return tree[x].key;
}
int getmax(int x)//求最大值
{
while(tree[x].right)
x=tree[x].right;
return tree[x].key;
}
int pred(int &x,int y,int key)//前驱,y初始前驱,从0開始, 终于要的是返回值的key值
{
if(x==0)
return y;
if(key>tree[x].key)
return pred(tree[x].right,x,key);
else
return pred(tree[x].left,y,key);
}
int succ(int &x,int y,int key)//后继。同上
{
if(x==0)
return y;
if(key<tree[x].key)
return succ(tree[x].left,x,key);
else
return succ(tree[x].right,y,key);
}
int select(int &x,int k)//选第k小的数
{
int r=tree[tree[x].left].size+1;
if(r==k)
return tree[x].key;
else
if(r<k)
return select(tree[x].right,k-r);
else
return select(tree[x].left,k);
}
int rank(int &x,int key)//key排第几
{
if(key<tree[x].key)
{
return rank(tree[x].left,key);
}
else
if(key>tree[x].key)
return rank(tree[x].right,key)+tree[tree[x].left].size+1;
else
return tree[tree[x].left].size+1;
}
void order(int &x)
{
if(x==0)
return;
order(tree[x].left);
printf("%d\n",tree[x].key);
order(tree[x].right);
}
int main()
{
top=0;
}
手写一个节点大小平衡树(SBT)模板,留着用的更多相关文章
- 剖析手写Vue,你也可以手写一个MVVM框架
剖析手写Vue,你也可以手写一个MVVM框架# 邮箱:563995050@qq.com github: https://github.com/xiaoqiuxiong 作者:肖秋雄(eddy) 温馨提 ...
- 手写一个LRU工具类
LRU概述 LRU算法,即最近最少使用算法.其使用场景非常广泛,像我们日常用的手机的后台应用展示,软件的复制粘贴板等. 本文将基于算法思想手写一个具有LRU算法功能的Java工具类. 结构设计 在插入 ...
- 【redis前传】自己手写一个LRU策略 | redis淘汰策略
title: 自己手写一个LRU策略 date: 2021-06-18 12:00:30 tags: - [redis] - [lru] categories: - [redis] permalink ...
- 『练手』手写一个独立Json算法 JsonHelper
背景: > 一直使用 Newtonsoft.Json.dll 也算挺稳定的. > 但这个框架也挺闹心的: > 1.影响编译失败:https://www.cnblogs.com/zih ...
- 教你如何使用Java手写一个基于链表的队列
在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...
- 【spring】-- 手写一个最简单的IOC框架
1.什么是springIOC IOC就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理. 如果我们手写一个最最简单的IOC,最终效果是怎样呢? xml配置: <b ...
- 放弃antd table,基于React手写一个虚拟滚动的表格
缘起 标题有点夸张,并不是完全放弃antd-table,毕竟在react的生态圈里,对国人来说,比较好用的PC端组件库,也就antd了.即便经历了2018年圣诞彩蛋事件,antd的使用者也不仅不减,反 ...
- 搞定redis面试--Redis的过期策略?手写一个LRU?
1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ...
- 手写一个简单的ElasticSearch SQL转换器(一)
一.前言 之前有个需求,是使ElasticSearch支持使用SQL进行简单查询,较新版本的ES已经支持该特性(不过貌似还是实验性质的?) ,而且git上也有elasticsearch-sql 插件, ...
随机推荐
- Hadoop之文件系统Shell
概述: 文件系统(FS)Shell包括各种类-Shell的命令.直接和Hadoop分布式文件系统(HDFS)交互,也支持对其它文件系统的支持.比如:本地文件系统FS,HFTP FS,S3 FS,和其它 ...
- Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析)
本文将介绍网络连接建立的过程.收发包流程,以及当中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 1.应用层 对于使用socket进行网络连接的server端程序.我们会先调用socket函 ...
- Hbase集群扩展
当hbase集群节点不够用时,我们须要新增节点来对集群进行扩展.hbase集群的扩展是非常easy的,过程例如以下: 一.准备一台新机器作为扩展节点,这里是作为slaves15,该机子要先与maste ...
- caioj1497&&bzoj3125: CITY
震惊!bzoj居然又被苏大佬D飞了... 这题煞笔模板题好吧. 然而bzojAC caiojWA%40??? 好强啊 今天早上发现是m打成n了囧 #include<cstdio> #inc ...
- 英语发音规则---N字母
英语发音规则---N字母 一.总结 一句话总结: 1.位于词尾的n在m后面时不发音? autumn /'ɔːtəm/ n. 秋天 column /'kɒləm/ n. 纵队 2.在音素/k//g/前面 ...
- 基于QMP实现对qemu虚拟机进行交互
本文详解QMP,包含qmp.hmp.qemu-guest-agent的介绍.工作原理.配置方法.范例 小慢哥的原创文章,欢迎转载 目录 ▪ QMP介绍 ▪ QMP语法 ▪ 单独使用qemu,启用QMP ...
- MSSQL执行大脚本文件时,提示“内存不足”的解决办法
导出了一个脚本文件,将近900M,回来往sql studio一丢,报了个内存不足,然后就有了此文.. 问题描述: 当客户服务器不允许直接备份时,往往通过导出数据库脚本的方式来部署-还原数据库, 但是当 ...
- HDU 1575 矩阵快速幂裸题
题意:中文题 我就不说了吧,... 思路:矩阵快速幂 // by SiriusRen #include <cstdio> #include <cstring> using na ...
- 【转】sql 一对多情况下 Group by分组 结果多列合并
部分原始表数据 需求: 按routineId进行group分组 初步想法(错误): select r * from autowork.dbo.PartOnRoutine where routineId ...
- RxSwift 之变换操作
https://www.aliyun.com/jiaocheng/349821.html RxSwift入坑解读-你所需要知道的各种概念 http://www.open-open.com/lib/vi ...