原理:https://blog.csdn.net/u013011841/article/details/39158585
一.跳表结构
一种插入、查询、删除时间效率为O(log n)空间效率为O(n)的数据结构,效率堪比红黑树,但是实现起来更加简易,内存空间使用更小,便于调试。
1.节点
class node {
int val
;
int level
;
node
* forword
[MAXLEVEL
];
};
2.skiplist(管理整个表的一个数据结构)
class skiplist {
private:
node
* head
;
int max_length
;
}
随机生成level算法
int randomLevel() {
int k
= 1;
while (rand() % 2) {
k
++;
}
k
= (k
< MAXLEVEL
) ? k
: MAXLEVEL
;
return k
;
}
二、具体实现
class node {
public:
node(int val
,int level
) {
this->val
= val
;
this->level
= level
;
for (int i
= 0; i
< MAXLEVEL
; i
++) {
forword
[i
] = NULL;
}
}
~node() {
}
int val
;
int level
;
node
* forword
[MAXLEVEL
];
};
class skiplist {
public:
skiplist() {
max_length
= 0;
node
* p
= new node(0, 5);
head
= p
;
}
void insert(int val
) {
int level
= randomLevel();
max_length
++;
if (head
== NULL) {
node
* p
= new node(val
,MAXLEVEL
);
head
= p
;
max_length
++;
}
else {
node
* cur
= head
;
node
* p
= new node(val
, level
);
node
* last
[MAXLEVEL
];
for (int i
= MAXLEVEL
-1; i
>= 0; i
--) {
while (cur
->forword
[i
] != NULL && cur
->forword
[i
]->val
< val
) {
cur
= cur
->forword
[i
];
}
last
[i
] = cur
;
}
if(cur
->forword
[0]==NULL){
for (int i
= p
->level
-1; i
>= 0; i
--) {
last
[i
]->forword
[i
] = p
;
}
}
else if (cur
->forword
[0]->val
> val
) {
for (int i
= p
->level
-1; i
>= 0; i
--) {
p
->forword
[i
] = last
[i
]->forword
[i
];
last
[i
]->forword
[i
] = p
;
}
}
}
}
void search(int val
) {
node
* cur
= head
;
for (int i
= MAXLEVEL
- 1; i
>= 0; i
--) {
while (cur
->forword
[i
]!=NULL&&cur
->forword
[i
]->val
<val
) {
cur
= cur
->forword
[i
];
}
if (cur
->forword
[i
]!=NULL&&cur
->forword
[i
]->val
== val
) {
cout
<< "i search it " << endl
;
return;
}
}
cout
<< "not find" << endl
;
}
void delete_val(int val
) {
node
* cur
= head
;
node
* ask
=NULL;
node
* last
[MAXLEVEL
];
for (int i
= MAXLEVEL
- 1; i
>= 0; i
--) {
while (cur
->forword
[i
] != NULL && cur
->forword
[i
]->val
< val
) {
cur
= cur
->forword
[i
];
}
last
[i
] = cur
;
if (cur
->forword
[i
] != NULL && cur
->forword
[i
]->val
== val
) {
ask
= cur
->forword
[i
];
}
}
for (int i
= ask
->level
- 1; i
>= 0; i
--) {
last
[i
]->forword
[i
] = ask
->forword
[i
];
}
delete(ask
);
}
void print() {
for (int i
= MAXLEVEL
-1; i
>= 0; i
--) {
node
* cur
= head
;
while (cur
->forword
[i
]) {
cur
= cur
->forword
[i
];
cout
<< cur
->val
;
}
cout
<< endl
;
}
}
int get_max_length() {
return max_length
;
}
private:
node
* head
;
int max_length
;
};
三、测试
int main() {
skiplist t1
;
t1
.insert(3);
t1
.insert(7);
t1
.insert(4);
t1
.insert(6);
t1
.insert(5);
t1
.insert(-1);
t1
.delete_val(4);
t1
.search(8);
t1
.print();
system("pause");
return 0;
}
运行结果: 注:print()函数打印的为跳表从最左节点打到最后,从上往下打。 跳表实现成功!
四、反思
编写的时候出现了两个bug:
二级指针的建立 我想用二级指针node** last来保存前面的节点(node*),或者是保存每个节点的forword指针,以便减少内存。结果导致debug时间一个小时,整个程序都是乱的。
错误的初始化:
node
** forword
;
forword
= (node
**)malloc(sizeof(node
*) * level
);
应当改为: 其中forword为node数组,node[0]:node,node[1]:node*… 数组的大小为level
forword
=new node
*[level
];
level下标越界 for循环写成for(int i=level;i>=0;i++),应当为i=level-1