大家好,我是 DongGu ,是一名软件工程专业大三的学生,写博客一方面是为了记录自己的学习过程,把自己犯的错误进行分享。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!有任何问题可以评论 或者 ___>> QQ联系(1521839703)
- 一开始看这个确实头疼, 每个node节点还有一个数组指针,有点麻了,不懂其结果,后面用了一个show函数,就能看清楚,其实每个数组指针,其实可以看做一个链表, 相当于维护了n个n长度的链表,这个确实可以再优化一下,改成动态开辟的,已经查找删除的时候, 可以用个双链表,这样子更快实现,
- 具体看代码吧,有注释~
简单,未加动态插入
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXLEVEL 10
class Node {
public:
int data;
Node* next[MAXLEVEL];
};
class SkipList {
public:
Node* m_phead;
int m_nowlevel;
SkipList();
~SkipList();
void show();
int insert(int addData);
Node* find(int findData);
int del(int delData);
};
SkipList::SkipList() {
m_nowlevel = 0;
m_phead = new Node();
for (int i = 0; i < MAXLEVEL; ++i) m_phead->next[i] = nullptr;
}
SkipList::~SkipList() {
delete m_phead;
cout << "~SkipList()\n";
}
int SkipList::insert(int addData) {
int k = m_nowlevel;
Node* prev[MAXLEVEL] = {}, * p = m_phead, * q;
while (k >= 0)
{
q = p->next[k];
while (q != nullptr && q->data < addData) {
p = q; // p 就是 < addData 的节点 不断更新记录
q = q->next[k];
}
if (q != nullptr && q->data == addData) {
cout << "is live\n";
return 1;
}
prev[k] = p;
--k; //往下一层链表搜索
}
k = rand() % MAXLEVEL;
if (k > m_nowlevel) {
k = ++m_nowlevel;
prev[k] = m_phead;
}
p = new Node();
p->data = addData;
//类似于给k个链表做插入 p节点
for (int i = 0; i <= k; ++i) {
p->next[i] = prev[i]->next[i]; // prev[i] : i层的节点, prev[i]->next[i];i层的节点的第几层数据
prev[i]->next[i] = p;
}
for (int i = k + 1; i < MAXLEVEL; ++i) p->next[i] = nullptr;
return 0;
}
Node* SkipList::find(int findData) {
int k = m_nowlevel;
Node* p = m_phead, * q;
int cnt = 0;
while (k >= 0) {
q = p->next[k];
++cnt;
while (q && q->data < findData) {
p = q;
q = q->next[k];
++cnt;
}
if (q && q->data == findData) {
cout << "find --> " << cnt << endl;
return q;
}
--k; // 下一层
}
return nullptr;
}
int SkipList::del(int delData) {
int k = m_nowlevel;
Node* p = m_phead, * q, * prev[MAXLEVEL] = {};
Node* delpos = find(delData);
if (delpos == nullptr) return 1;
while (k >= 0) {
q = p->next[k];
while (q && q->data < delData) {
p = q;
q = q->next[k];
}
if (q && q->data == delData) {
prev[k] = p;
}
k--;
}
for (int i = 0; i <= m_nowlevel; ++i) {
if (prev[i])
prev[i]->next[i] = delpos->next[i];
}
delete delpos;
return 0;
}
void SkipList::show() {
Node* head = m_phead;
for (int i = m_nowlevel; i >= 0; i--) {
//cout << "head-->";
printf("%p-->", head);
Node* tmp = head->next[i];
for (int j = 0; j < MAXLEVEL; j++)
{
if (tmp != nullptr) {
printf("%p【%d】-->", tmp, tmp->data);
}
else
{
cout << "tail";
break;
}
tmp = tmp->next[i];
}
cout << endl;
}
}
int main()
{
// 检测是否有内存泄漏
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
SkipList* p = new SkipList();
for (int i = 1; i <= 5; i++) {
p->insert(i);
p->show();
printf("\n\n");
}
for (int i = 1; i <= 5; i++) {
cout << p->find(i);
printf("\n\n");
}
for (int i = 1; i <= 5; i++) {
cout << p->del(i);
printf("\n\n");
}
delete p;
return 0;
}
动态插入
int SkipList::insert(int addData) {
int k = m_nowlevel;
Node* prev[MAXLEVEL] = {}, * p = m_phead, * q;
while (k >= 0)
{
q = p->next[k];
while (q != nullptr && q->data < addData) {
p = q; // p 就是 < addData 的节点 不断更新记录
q = q->next[k];
}
if (q != nullptr && q->data == addData) {
cout << "is live\n";
return 1;
}
prev[k] = p;
--k; //往下一层链表搜索
}
srand(time(0));
int up = 1;
int level = 0;
p = new Node();
p->data = addData;
while (up)
{
if (level > m_nowlevel) {
m_nowlevel = level;
p->next[level] = m_phead;
m_phead->next[level] = p;
break;
}
if (prev[level] == nullptr) break;
p->next[level] = prev[level]->next[level]; // prev[level] : level层的节点, prev[level]->next[level];level层的节点的第几层数据
prev[level]->next[level] = p;
int d = rand() % 1234;
printf("----%d----\n", d);
up = (d & 1) == 0;
++level;
}
//k = rand() % MAXLEVEL;
//if (k > m_nowlevel) {
// k = ++m_nowlevel;
// prev[k] = m_phead;
//}
//p = new Node();
//p->data = addData;
类似于给k个链表做插入 p节点
//for (int i = 0; i <= k; ++i) {
// p->next[i] = prev[i]->next[i]; // prev[i] : i层的节点, prev[i]->next[i];i层的节点的第几层数据
// prev[i]->next[i] = p;
//}
for (int i = level; i < MAXLEVEL; ++i) p->next[i] = nullptr;
return 0;
}