跳表就是一种特殊的单链表,这个单链表的头节点有很多层,从每一层头节点往后看去,它都是一个有序的单链表。那么跳表怎样增删改查呢?
1.插入节点的时候,先利用随机函数随机产生该节点的层数,如果跳表中不存在这一层,就创建到这一层,然后对新创建的每一层都进行插入,如果存在这一层,依次往后遍历,找到前一个小于它,后一个大于它的节点位置进行插入。
2.删除节点同理,不过需要注意的是,如果删除掉该节点之后,这一层为空,就把这一层链表整个删除掉。
3.查找节点的时候,从最高层开始遍历,找到该值就依次向下遍历,返回第一层的该值
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define MAX_LEVEL 30
//每个节点的结构体
typedef struct node {
node * right;
node * down;
int key;
} data_node ;
//跳表的结构体,分别包括多层头节点指针,头节点最大层数,size是跳表中元素总个数
struct skip_list {
data_node ** header;
int max_level;
int size;
};
//定义一个节点数组,后面数组里保存插入的节点
node * height[MAX_LEVEL];
//随机产生要插入节点总共应该插入几层
int get_current_level()
{
int k = 0;
//在[0,2)中产生随机数,当随机数小于1时跳出
while(rand()%2) ++k;
return k;
}
//跳表的初始化
skip_list * skip_list_init()
{
//用系统时间获取随机数种子,防止随机数每次重复
srand((unsigned)time(NULL));
//定义一个跳表指针
skip_list * sl;
//开辟一段跳表空间
sl = new skip_list();
//初始化该跳表的最大层数为0
sl->max_level = 0;
//跳表中的头节点数组指针指向开辟的节点数组
sl->header = new data_node* [MAX_LEVEL];
//开辟MAX_LEVEL个节点,把这些节点放到跳表的头节点数组中
//每个头节点初值都是-10
for(int i = 0; i< MAX_LEVEL; ++i) {
data_node * t = new data_node();
//有一个头节点的作用是为了后面方面增删改查的操作
t->key = -10;
t->right = NULL;