下午略忙,伸展树有点难,(6)(7)(8)篇先跳过,先写简单的
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
const int max_flow = 5; //确定最大层数为5
const int p = 5; //阈值,设一个差不多大的就好
class List_Node {
/*
链表类
值
下一个键
下一层键
*/
public:
int val;
List_Node* next_ptr;
List_Node* next_flow_ptr;
public:
List_Node() :next_ptr(NULL), next_flow_ptr(NULL) {}
List_Node(int v) :val(v), next_ptr(NULL), next_flow_ptr(NULL) {}
void set_next(List_Node* node){
next_ptr = node;
}
void set_next_flow(List_Node* node) {
next_flow_ptr = node;
}
};
class Skip_List {
public:
List_Node* flow_head; //最顶层的头
public:
Skip_List(){
flow_head = new List_Node();
}
/*
需要一个确定随机层数的函数
且需要层数越高概率越低
再来一个最高层数,以防层数过高(已设置为int全局常量
*/
int rand_flow() {
int rand_num = 0, flow = 0;
while (rand_num < p && flow < max_flow) {
srand(time(NULL));
rand_num = rand() % (p * 2);
flow++;
}
return flow; //可保至少有一层
}
void create_skip_list() {
/*
初始化链表
确定层数
返回最高层的头结点(反正后面的节点也是点点相连)
*/
//直接max_flow层吧
int i = 1;
List_Node* temp = flow_head;
while (i < max_flow) {
temp->next_flow_ptr = new List_Node();
temp = temp->next_flow_ptr;
i++;
}
}
//插入节点,不过还需要一个辅助函数
List_Node* insert(List_Node* slow,int val) {
//辅助函数,将节点插入在某一层,并将插入的节点返回
List_Node* temp = slow;
List_Node* node = new List_Node(val); //不能放在上面,不然这几层还不得捆在一起了
while (temp && temp->val < val) {
temp = temp->next_ptr;
}
if (temp) { //还没到尾巴
node->next_ptr = temp->next_ptr;
}
temp->next_ptr = node;
return node;
}
void insert_node(int val) {
//确定插入层数
int f = rand_flow();
//找到那一层的头
List_Node* fast = flow_head;
List_Node* slow = flow_head;
for (int i = 0; i < f; i++) {
fast = fast->next_flow_ptr;
}
while (fast) {
fast = fast->next_flow_ptr;
slow = slow->next_flow_ptr;
}
delete fast;
//开始逐层插入
while (slow) {
slow->next_flow_ptr = insert(slow, val);
}
}
//搜寻节点
bool search_node(int val) {
List_Node* flow = flow_head;
while (flow) {
List_Node* temp = flow;
while (temp->next_ptr) {
if (val == temp->next_ptr->val) {
return true;
}
else if (val > temp->next_ptr->val) {
temp = temp->next_ptr;
if (temp->next_flow_ptr) { //如果途经过程中有下家
flow = temp;
}
}
else { //如果在遍历的过程中发现本层并没有
flow = flow->next_flow_ptr;
break;
}
} //如果遍历完成后发现本层并没有
}
return false;
}
//删除节点
void delete_node(int val) {
/*
首先找到节点
然后将节点前后衔接上
删除节点的时候要判断是否有下家,如果有下家,一并删除
*/
List_Node* flow = flow_head;
while (flow) {
List_Node* temp = flow;
while (temp->next_ptr) {
if (val == temp->next_ptr->val) {
List_Node* del_temp = temp->next_ptr;
if (del_temp->next_flow_ptr) { //如果有下家
//这个有下家还真有点麻烦呐
//不过还好我两手准备
temp->next_ptr = temp->next_ptr->next_ptr;
del_temp->next_ptr = NULL;
delete del_temp;
flow = flow->next_flow_ptr;
break;
}
else {
temp->next_ptr = temp->next_ptr->next_ptr;
del_temp->next_ptr = NULL;
delete del_temp;
return;
}
}
else if (val > temp->next_ptr->val) {
temp = temp->next_ptr;
if (temp->next_flow_ptr) { //如果途经过程中有下家
flow = temp;
}
}
else { //如果在遍历的过程中发现本层并没有
flow = flow->next_flow_ptr;
break;
}
} //如果遍历完成后发现本层并没有
}
}
};