用最简单的语言, 一定看得懂 【C++简单实现跳表的增删查改, 还需优化】

大家好,我是 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DongGu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值