手写一个节点大小平衡树(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 插件, ...
随机推荐
- Hdu 4280 Island Transport(最大流)
Island Transport Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- phpstudy配置多个域名
phpstudy配置多个域名 1.端口配置对应的文件为PHPTutorial\Apache\conf\httpd.conf 直接在这个文件里面搜索localhost就可以搜到上图对应的代码那一块 第一 ...
- xargs用例一个
ls -a *.doc|awk -F. '{print $1}' |xargs -I {} java -jar ~/soft/jodconverter-2.2.2/lib/jodconverter-c ...
- Oracle 11G R2 用exp无法导出空表解决方法
四. Oracle 10g以后增加了expdp和impdp工具,用此工具也可以导出空的表 oracleexpdp/impdp 用法详解 1) 创建逻辑目录,该命令不会在操作系统创建真正的目录,最好 ...
- 剑指offer——03从尾至头打印列表(Python3)
思路:相当于数据结构中的链表就地逆置,可以使用头插法来实现. 代码: class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListF ...
- Linux 安装Redis 5.0
结构如下: Redis 官方不建议Redis安装在WINDOWS 服务器上(尤其是生产中分布式事物缓存). linux 下Redis 5.0主从复制(一主二从)哨兵模式的搭建:https://www. ...
- 【翻译】前景img-sprites, 高对比模式分析
->译文,原文在这里<- 本文地址: http://www.cnblogs.com/blackmanba/p/img-sprites-high-contrast.html或者http:// ...
- 开源UWP总结
1.UWP第三方简书客户端分享:http://www.cnblogs.com/youngytj/p/4889010.html 2.知乎日报:http://www.cnblogs.com/xiaozhi ...
- Codeforces 994A. Fingerprints
题意 从x数组中找到最多的y数组中有的数字,按在x数组中出现的顺序输出. 注意 这题x数组和y数组都不会出现重复数字. 代码 #include <bits/stdc++.h> using ...
- 关于CR0寄存器
开始的时候,我认为CR0.WP如果被置位,那么内存的页面只读属性将会失效,导致可以被写入数据. 这几天正好碰到一个问题,查看了资料才发现,之前的理解不完整. 引用Intel手册中的一句话: CR0.W ...