手写一个节点大小平衡树(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 插件, ...
随机推荐
- Linux下FFmpeg的安装编译过程【转】
本文转载自:http://www.linuxidc.com/Linux/2013-06/85628.htm 详细说下在Linux下FFmpeg的安装编译过程.参考 Ubuntu 10.04安装编译FF ...
- c语言数组小谈
#include <stdio.h> #include <stdlib.h> #define N 5 int main() { double score[5]; int i; ...
- org/eclipse/jetty/util/component/Container$Listener
转自:https://blog.csdn.net/husheng8891/article/details/10200965?locationNum=9&fps=1 项目Demo开发的时候,发布 ...
- SQLserver中用convert函数转换日期格式(2)
), ): :57AM ), ): ), ): ), ): ), ): ), ): ), ): ), ): , ), ): :: ), ): :::827AM ), ): ), ): ), ): ), ...
- python程序执行原理
Python程序的执行原理 1. 过程概述 Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器一条一条执行字节码指令,从而完成程序的执行. 1.1python先把代码(.py ...
- quartz定时任务框架调度机制解析
转自集群调度机制调研及源码分析 quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 qurat ...
- IntelliJ Idea下Go项目开启Debug调试
1.新建Go项目,创建入口go文件(Test1.go),随便写点啥,比如: package main import "fmt" func main(){ fmt.Println(& ...
- NGUI 按钮点击事件的两种绑定形式
面板属性栏绑定 写一个脚本,定义一个Public的方法 Notify中选择物体时,选中自己 然后就可以选择通知到写的那个脚本的里边的public方法 代码绑定 创建一个代码文件,挂载到按钮对象上 代码 ...
- ZBrush软件特性之Edit
ZBrush®中的Edit调控板控制撤销和重做命令,它有一或两个命令设置将根据Tool工具调控板当前选择的工具而定,默认配置的命令仅有文档编辑,不过当激活一个3D工具,只针对这个工具的两个按钮设置变成 ...
- Pyhton学习——Day11
# Python中的内部模块# 函数学习的意义:抽取重复代码# 模块:不用重复写,模块及py文件,提高了代码的可维护性,其次,编写代码不必从零开始,当一个模块编写完毕,不必再重复编写# import ...