要求
实现并分析跳表结构
构造并实现跳表ADT,跳表ADT包括如下操作:
初始化跳表
查找跳表内是否存在元素x
向跳表插入元素x
删除跳表内元素x,若不存在则抛出异常
删除跳表内关键字最小的元素
删除跳表内关键字最大的元素
其他根据需要实现,注意数据的可访问性
格式
输入格式
输入包含 1+n+m 行数据
第一行包含两个数字 n, m (0 \leq n \leq 1000, 0 \leq m \leq 10000≤n≤1000,0≤m≤1000)
之后的 n 行,每行包含一个数字与一个字符串,表示一个元素,数字为跳表的关键字(0\leq key \leq 1,000,000,000)(0≤key≤1,000,000,000),字符串为元素的值。
之后的 m 行表示 m 个跳表ADT操作。每行第一个数字 a 用来区别操作。
a 为 1 时,表示查找操作,其后的一个数字 b 为要查询的元素的关键字, 输出 该元素的值,不存在则输出 -1。
a 为 2 时,表示插入操作,其后的一个数字 b 为要插入的元素,一个字符串 c 为对应的值, 不输出 。
a 为 3 时,表示删除操作,其后的一个数字 b 为要删除的关键字, 输出 该关键字与其对应的元素值,若删除关键字不存在或删除失败,输出 -1。
a 为 4 时,表示删除最小元素操作。 输出 跳表内最小关键字 c 与其对应的元素值,并将对应元素在跳表内部删除
a 为 5 时,表示删除最大元素操作。 输出 跳表内最大关键字 c 与其对应的元素值,并将对应元素在跳表内部删除
输出格式
请根据输入描述,完成跳表的相应操作,输出正确的信息
样例
输入
3 6
10 apple
1 mi
5 oops
1 10
2 7 oppo
3 4
3 5
4
5
输出
apple
-1
5 oops
1 mi
10 apple
可能出现的问题:
删除时不是指删除找到的第一个元素
要继续下一层查找 元素会同时存在多层
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
typedef int Key;
int maxlevel=20;
struct item{Key key;
};
typedef struct sknode* link;
struct sknode{//建结构
item it;//元素->用来排序
string str;//元素值
link *next;//指向下一个节点
int s;//连接数
};
link head;//头指针
link endd;//尾指针
int allnode;//节点总数
int highlevel;//层数
struct item NULLit;//判断空
string NULLstr="-1";//判断空
Key key(item it){
return it.key;
}
link NEW(item it,string str,int s){
link x=new sknode;//使用new使得string分配到空间
//x->next=new sknode*;//若值不为string类型可用
x->next=(link *)malloc(s*sizeof(link));
x->it=it;
x->s=s;
if(str!="-1"){x->str=str;
}
for(int i=0;i<s;i++){
x->next[i]=endd;
}
return x;
}
void skinit(){//初始化
allnode=0;highlevel=0;
endd=NEW(NULLit,NULLstr,1000);
head=NEW(NULLit,NULLstr,maxlevel+1);
}
int randnode(){//随机数生成
int i,j,t=rand();
for(i=1,j=2;i<maxlevel;i++,j+=j){
if(t>RAND_MAX/j){break;
}
}
if(i>highlevel){
highlevel=i;
}
return i;
}
void insert(link t,link x,int s){//t:原跳表 x:插入元素 s:层数
Key v=key(x->it),u=key(t->next[s]->it);
if(v<u||u==0){
if(s<x->s){
x->next[s]=t->next[s];
t->next[s]=x;
}
if(s==0){return;
}
insert(t,x,s-1);return;//这层不应该被插入 从下一层开始找
}
}
insert(t->next[s],x,s);//下一个元素
void skinsert(item it,string str){
insert(head,NEW(it,str,randnode()),highlevel);
allnode++;
}
void deletenode(link t,Key k,int s){//t:原跳表 k:插入元素 s:层数
if(t==endd){cout<<-1<<endl;return;
}
link x=t->next[s];
if(!(key(x->it)<k)||key(x->it)==0){
if(k==key(x->it)){//找到元素
t->next[s]=x->next[s];//链表删除
if(s==0){cout<<k<<' '<<x->str<<endl;return;
}
}
if(s==0){cout<<"-1"<<endl;return;//层数归零
}
deletenode(t,k,s-1);return;//这层未找到元素 从下一层开始找
}
deletenode(t->next[s],k,s);//下一个元素
}
void skdelete(Key k){
deletenode(head,k,highlevel);
allnode--;
}
void search(link t,Key k,int s){//查找
if(t==endd){cout<<-1<<endl;return;
}
if(k==key(t->it)){cout<<t->str<<endl;return ;
}
Key u=key(t->next[s]->it);
if(k<u||u==0){
if(s==0){cout<<"-1"<<endl;return;
}else{search(t,k,s-1);return;//下一层
}
}
search(t->next[s],k,s);//下一个元素
}
void sksearch(Key k){
search(head,k,highlevel);
}
void searchsmall(){//头结点的下一个为最小元素
link t= head;
skdelete(key(t->next[0]->it));return;
}
void searchbig(){//第0层节点遍历后的最后一个为最大元素
link t = head ;
while(t->next[0] !=endd){
if(t->next[0]->next[0]==endd){skdelete(key(t->next[0]->it));return;
}
t = t->next[0];
}
}
void p(){//遍历所有元素
link t = head ;
while(t->next[0] !=endd){
cout<<t->next[0]->it.key<<' '<<t->next[0]->str<<endl;
t = t->next[0];
}
cout<<endl;
}
int main(){
int n,m;
skinit();//初始化
int a;
string st;
item nu;
cin>>n>>m;
for(int i=0;i<n;i++){//插入
cin>>nu.key>>st;
skinsert(nu,st);
}
for(int i=0;i<m;i++){
cin>>a;
if(a==1){//查找
cin>>a;
sksearch(a);
}else if(a==2){//插入元素
cin>>nu.key>>st;
skinsert(nu,st);
}else if(a==3){//删除指定元素
cin>>a;
skdelete(a);
}else if(a==4){//删除最小
searchsmall();
}else if(a==5){//删除最大
searchbig();
}
}
//p();
}