创建AVL树,插入,删除,输出Kth Min
https://github.com/TouwaErioH/subjects/tree/master/C%2B%2B/PA2
没有考虑重复键,可以在结构体内加一个int times。
没有考虑删除不存在的键,加个判断即可。
#include <stdio.h>
#include <assert.h>
#include<iostream>
#include <algorithm>
#include <algorithm>
using namespace std;
int cnt=0;
int max(int a, int b)
{
return (a > b ? a : b);
}
struct node
{
int key;
int height;
int size; //tree node 个数
node *left, *right;
/*
node(int x) : key(x), height(1), size(1), left(NULL), right(NULL) {}
node() : key(NULL), height(NULL), size(NULL), left(NULL), right(NULL){}
*/
node(int k)
{
key = k;
height = 1;
size = 1;
left = right = 0;
}
}; int height(node* r)
{
return r ? r->height : 0;
} void update_height(node* root)
{
root->height = max(height(root->left), height(root->right)) + 1;
} int sizeOfTree(node* root){
return root == NULL? 0 : root->size;
} void right_rotate(node*& ref_root)
{
node *y = ref_root->left;
ref_root->left = y->right;
y->right = ref_root; ref_root->size = sizeOfTree(ref_root->left) + sizeOfTree(ref_root->right) + 1;
update_height(ref_root);
y->size = sizeOfTree(y->left) + sizeOfTree(y->right) + 1;
update_height(y);
ref_root=y;
} void left_rotate(node*& ref_root)
{
node *y = ref_root->right;
ref_root->right = y->left;
y->left = ref_root; ref_root->size = sizeOfTree(ref_root->left) + sizeOfTree(ref_root->right) + 1;
update_height(ref_root);
y->size = sizeOfTree(y->left) + sizeOfTree(y->right) + 1;
update_height(y);
ref_root=y;
} //after deletion and insertion, maintain a balanced tree.
void maintain(node*& ref_root)
{
int balance=0;
if (!ref_root) return ;
update_height(ref_root);
balance = height(ref_root->left)-height(ref_root->right);
if (balance > 1)
{
if ((height(ref_root->left->left)-height(ref_root->left->right)) < 0) //LR
left_rotate(ref_root->left);
right_rotate(ref_root);
}
else if (balance < -1)
{
if ((height(ref_root->right->left)-height(ref_root->right->right)) > 0) //RL
right_rotate(ref_root->right);
left_rotate(ref_root);
}
} void insert_key(int key, node*& ref_root)
{
cnt ++;
node*p=new node(key);
if(!ref_root){
node*p=new node(key);
ref_root=p;
}
if(key < ref_root->key){
insert_key(key,ref_root->left);
ref_root->size=ref_root->size+1;
}
else if(key > ref_root->key){
insert_key(key,ref_root->right);
ref_root->size=ref_root->size+1;
}
/* calculate the height after insertion */
update_height(ref_root);
maintain(ref_root);
} void delete_key(int key, node*& ref_root)
{
if(key < ref_root->key){
ref_root->size=ref_root->size-1;
delete_key(key, ref_root->left);
}
else if(key > ref_root->key){
ref_root->size=ref_root->size-1;
delete_key(key,ref_root->right);
}
else {
if(!ref_root->left) {
struct node *temp = ref_root->right;
//free( ref_root);
ref_root = temp;
if(ref_root!=NULL)
ref_root->size=ref_root->size;
} else if(! ref_root->right) {
struct node *temp = ref_root->left;
//free (ref_root);
ref_root = temp;
} else {
struct node *temp = ref_root->right;
while(temp->left != NULL)
temp = temp->left;
ref_root->key = temp->key;
temp->key=key;
ref_root->size=ref_root->size-1;
delete_key(key,ref_root->right);
}
}
if(ref_root!=NULL)
update_height(ref_root);
maintain(ref_root);
} int KthMin(node * root, int k){
if(root->left!=NULL){
int lSize = sizeOfTree(root->left);
if (k <= lSize)
return KthMin(root->left, k);
else if (lSize + 1 < k)
return KthMin(root->right, k - lSize - 1);
return root->key;
}
else
{
if(root->right==NULL)
return root->key;
else if(k==1)
return root->key;
else
return KthMin(root->right, k - 1); }
} void printtree(node* root) {
if (root == NULL) {
return;
}
cout << root->key<<'X'<<endl;
cout<<"L"<<endl;
printtree(root->left);
cout<<"R"<<endl;
printtree(root->right);
if (root->left == NULL || root->right == NULL) {
return;
}
} void preOrder(node *root)
{
if(root != NULL)
{
printf("k %d s %d h %d ", root->key,root->size,root->height);
preOrder(root->left);
preOrder(root->right);
}
} int main()
{
node *root=NULL;
char op[10] = "";
int k;
while(true)
{
//if(cnt>1)
// { preOrder(root);/*printtree(root);*/}
scanf("%s", op);
if(op[0] == 'E') break;
switch(op[0])
{
case 'A': scanf("%d", &k); insert_key(k, root); break;
case 'D': scanf("%d", &k); delete_key(k, root); break;
case 'M': scanf("%d", &k); printf("%d\n", KthMin(root, k));break;
default: assert(0);
}
} return 0;
}
效果

创建AVL树,插入,删除,输出Kth Min的更多相关文章
- AVL树插入和删除
一.AVL树简介 AVL树是一种平衡的二叉查找树. 平衡二叉树(AVL 树)是一棵空树,或者是具有下列性质的二叉排序树: 1它的左子树和右子树都是平衡二叉树, 2且左子树和右子树高度之差的 ...
- AVL树插入操作实现
为了提高二插排序树的性能,规定树中的每个节点的左子树和右子树高度差的绝对值不能大于1.为了满足上面的要求需要在插入完成后对树进行调整.下面介绍各个调整方式. 右单旋转 如下图所示,节点A的平衡因子(左 ...
- AVL树插入(Python实现)
建立AVL树 class AVLNode(object): def __init__(self,data): self.data = data self.lchild = None self.rchi ...
- 链表的C++实现——创建-插入-删除-输出-清空
注:学习了数据结构与算法分析后,对链表进行了C++实现,参考博文:http://www.cnblogs.com/tao560532/articles/2199280.html 环境:VS2013 // ...
- 第七章 二叉搜索树 (d3)AVL树:删除
- AVL树的插入与删除
AVL 树要在插入和删除结点后保持平衡,旋转操作必不可少.关键是理解什么时候应该左旋.右旋和双旋.在Youtube上看到一位老师的视频对这个概念讲解得非常清楚,再结合算法书和网络的博文,记录如下. 1 ...
- AVL树(查找、插入、删除)——C语言
AVL树 平衡二叉查找树(Self-balancing binary search tree)又被称为AVL树(AVL树是根据它的发明者G. M. Adelson-Velskii和E. M. Land ...
- AVL树的插入和删除
一.AVL 树 在计算机科学中,AVL树是最早被发明的自平衡二叉查找树.在AVL树中,任一节点对应的两棵子树的最大高度差为 1,因此它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下的时间复杂度 ...
- 二叉平衡树AVL的插入与删除(java实现)
二叉平衡树 全图基础解释参考链接:http://btechsmartclass.com/data_structures/avl-trees.html 二叉平衡树:https://www.cnblogs ...
随机推荐
- [APUE] 进程环境
APUE 一书的第七章学习笔记. 进程终止 有 8 种方式可以使得进程终止,5 种为正常方式: Return from main Calling exit() Calling _exit or _Ex ...
- 深圳某小公司面试题:AQS是什么?公平锁和非公平锁?ReentrantLock?
AQS总体来说没有想象中那么难,只要了解它的实现框架,那理解起来就不是什么问题了. AQS在Java还是占很重要的地位的,面试也是经常会问. 目前已经连载11篇啦!进度是一周更新两篇,欢迎持续关注 [ ...
- 一键测试VPS到国内速度脚本 SuperBench.sh,以及一键验收云主机脚本
我们买国外VPS服务器测试网络通常会用到speedtest,speedtest默认是测试到最近的节点,那么到国内速度如何呢?虽然可以指定服务器编号,但是一个个测试还是比较麻烦的,这里推荐一个脚本整合了 ...
- chain issues incorrect order,EXtra certs,Contains anchor
背景: 下载颁发下来的ssl证书安装好之后网站正常显示安全,但是通过ssl证书网站去检测报错误:chain issues incorrect order,EXtra certs,Contains an ...
- ADB 基本命令
ADB很强大,记住一些ADB命令有助于提高工作效率. 获取序列号: adb get-serialno 查看连接计算机的设备: adb devices 重启机器: adb reboot 重启到bootl ...
- jmeter---线程组执行顺序记录
一.默认未勾选测试计划中独立运行每个线程组时,线程组并行执行,如下,设置三个请求,每个线程组设置5秒启动5个线程. 未勾选独立运行 运行结果如下,三个线程并行执行 勾选后,一个线程组执行完后才执行下一 ...
- 浅析Redis与IO多路复用器原理
为什么Redis使用多路复用I/O Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导 ...
- CentOS7.9静默安装Oracle19C软件
CentOS7.9静默安装Oracle19C软件 Oracle发布了支持的版本.可以看到了Oracle11gR2和Oracle12C.一直到2022年就不支持patch和服务.(感慨Oracle 11 ...
- 陈思淼:阿里6个月重写Lazada,再造“淘宝”的技术总结
小结: 1. 所谓的中台技术,就是从 IDC,网络,机房,操作系统,中间件,数据库,算法平台,数据平台,计算平台,到业务平台,每一层都有清晰的定义和技术产品. 具体来看,首先,集团技术的分层和每层的产 ...
- 固定学习率梯度下降法的Python实现方案
应用场景 优化算法经常被使用在各种组合优化问题中.我们可以假定待优化的函数对象\(f(x)\)是一个黑盒,我们可以给这个黑盒输入一些参数\(x_0, x_1, ...\),然后这个黑盒会给我们返回其计 ...