创建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 ...
随机推荐
- 【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
任务描述 本次集中介绍使用Windows和Linux()搭建本地Redis服务器的步骤,从备份的RDB文件中加载数据,以及如何生成AOF文件和通过AOF文件想已经运行的Redis追加数据. 操作步骤 ...
- 给HTML页面设置自己的icon
原因: 不知道为什么,SpringBoot中自动设置icon失效了. 解决方法: 在head标签中添加自己想要使用的icon图片.后缀使用图片格式,不要使用.ico. <link href=&q ...
- Ubuntu源、Python虚拟环境及pip源配置
Ubuntu 命令行更改源 在修改source.list前,最好先备份一份 软件源的地址配置文件在 /etc/apt/sources.list 执行备份命令 sudo cp /etc/apt/sour ...
- 【pytest】(十)fixture参数化-巧用params和ids优雅的创建测试数据
我们都知道参数化. 比如我要测试一个查询接口/test/get_goods_list,这个接口可以查询到商品的信息. 在请求中,我可以根据请参数goods_status的不同传值,可以查询到对应状态的 ...
- 解决Ajax同源政策的方法【JSONP + CORS + 服务器端解决方案】
解决Ajax同源政策的方法 使用JSONP解决同源限制问题 jsonp是json with padding的缩写,它不属于Ajax请求,但它可以模以Ajax请求.\ 步骤 1.将不同源的服务器端请求地 ...
- jQuery 自动生成二维码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ...
- Linux服务器内存池技术是如何实现的
Linux服务器内存池技术是如何实现的
- (ETL)ETL架构师面试题(转载)
1. What is a logical data mapping and what does it mean to the ETL team?什么是逻辑数据映射?它对ETL项目组的作用是什么? 答: ...
- Redis击穿、穿透、雪崩产生原因以及解决思路
击穿 大家都知道,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生了缓存,将一些热点数据放在内存中,随用随取,降低连接到数据库的请求链接,避免数据库挂掉.需要注意的是,无论是击穿还是 ...
- size_t 、wchar_t和 ptrdiff_t
size_t在C语言中就有了. 它是一种"整型"类型,里面保存的是一个整数,就像int, long那样.这种整数用来记录一个大小(size).size_t的全称应该是size ty ...