创建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 ...
随机推荐
- Sgu149 Computer Network
Sgu149 Computer Network 题目描述 给你一棵N(N<=10000)个节点的树,求每个点到其他点的最大距离. 不难想到一个节点到其他点的最大距离为:max(以它为根的子树的最 ...
- 学习Java第三天
方法重载:同一个类,方法名相同,参数不同(个数不同,类型不同,顺序不同),判断是否重载,只看方法名和参数,跟返回值无关. IDEA查看方法源代码:Crtl + 鼠标左键 进制表示 Java数值默认为十 ...
- 【Android初级】如何动态添加菜单项(附源码+避坑)
我们平时在开发过程中,为了灵活多变,除了使用静态的菜单,还有动态添加菜单的需求.今天要分享的功能如下: 在界面的右上角有个更多选项,点开后,有两个子菜单:关于和退出 点击"关于", ...
- 一键测试VPS到国内速度脚本 SuperBench.sh,以及一键验收云主机脚本
我们买国外VPS服务器测试网络通常会用到speedtest,speedtest默认是测试到最近的节点,那么到国内速度如何呢?虽然可以指定服务器编号,但是一个个测试还是比较麻烦的,这里推荐一个脚本整合了 ...
- oblet
oblet - The Go Programming Language https://golang.google.cn/search?q=oblet // put enqueues a poin ...
- Uber三代API 生命周期管理平台实现 Uber
Uber三代API 生命周期管理平台实现 - InfoQ https://www.infoq.cn/article/H8Ml6L7vJGQz0efpWvyJ Uber 三代 API 生命周期管理平台实 ...
- Go GC: Latency Problem Solved
https://talks.golang.org/2015/go-gc.pdf https://www.oschina.net/translate/go-gc-solving-the-latency- ...
- Linux进程内存用量分析之堆内存篇
https://mp.weixin.qq.com/s/a6mLMDinYQGUSaOsGYCEaA 独家|Linux进程内存用量分析之堆内存篇 姬晨烜 58技术 2019-12-06 导语 本文将介绍 ...
- 端口被占用通过域名的处理 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则
负载均衡-Nginx中文文档 http://www.nginx.cn/doc/example/loadbanlance.html 负载均衡 一个简单的负载均衡的示例,把www.domain.com均衡 ...
- WebServices 与 Web API 的区别
WebServices : WebServices 是可以通过 Internet 访问并通过 XML 编码规范其通信的任何服务. 客户通过发送请求(大部分是 XML消息)来召唤 WebServices ...