【高阶DS】跳表

跳跃表:

跳跃表(Skip List)是一种数据结构,用于在有序链表的基础上实现快速的查找、插入和删除操作。其基本思想是通过在原始有序链表的基础上增加多层索引,以加快查找速度。

算法思想:

1.创建一个有序链表作为底层索引,包含所有元素,并且保持有序。

2.在底层链表的基础上,创建多层索引。每一层索引都是原始链表的一个子集,其中第一层索引包含所有元素,第二层索引包含部分元素,第三层索引包含更少的元素,以此类推。

3.在每一层索引中,节点之间以指针相连,使得可以在不同层次上进行跳跃式的查找。

当进行查找、插入或删除操作时,从最高层的索引开始,逐层向下进行查找,直到找到目标元素或者找到插入或删除位置。

4.在跳跃表中进行插入或删除操作时,需要同时更新多层索引,以保持跳跃表的平衡性。

跳跃表的平均查找、插入和删除操作的时间复杂度为O(log n),其中n为元素的个数。因此,跳跃表是一种高效的数据结构,适用于需要快速查找、插入和删除操作的场景。

typedef struct ListNode
{
	int val=range+1;//设置头节点的val为最大值+1
	ListNode* arr[10]={nullptr};//这个10是随便取得,根据层数决定
}ListNode,*pListNode;

void SkipList(pListNode pnode)
{
	int k = 0;//层数-1
	int m = 1;//每一层的数据个数
	int n = Maxnum;
	//pListNode pnode = new ListNode;

	//由于没有数据填充,我这里采用随机数填充。这里也可以根据数据填充
	srand((unsigned)time(nullptr));
	while (n > 0)
	{
		//创建随机数节点
		int first = rand() % range + 1;
		pListNode newp = new ListNode;
		newp->val = first;
		newp->arr[k] = pnode->arr[k];
		pnode->arr[k] = newp;

		int i = m - 1;
		while (i)
		{
			pListNode p = pnode;

			//创建随机数节点
			int insert = rand() % range + 1;
			pListNode newp = new ListNode;
			newp->val = insert;

			while (p)
			{
				//去掉与上一级一样的
				/*for (pListNode pl = pnode->arr[k - 1]; pl; pl = pl->arr[k - 1])
				{
					if (newp->val == pl->val)
						goto next;
				}*/

				//判断下一个是否为空,为空则直接尾插
				if (!p->arr[k])
				{
					p->arr[k] = newp;
					break;
				}

				//判断什么时候插入
				if (p->arr[k]->val<newp->val && p->val > newp->val)
				{
					newp->arr[k] = p->arr[k];
					p->arr[k] = newp;
					break;
				}

				p = p->arr[k];

				//相同不进行插入
				if (p->val == insert)
					break;
			}
			//next:
			--i;

			//加入上一级的点并排序
			if (i == 0)
			{
				for (pListNode p1 = pnode->arr[k - 1]; p1; p1 = p1->arr[k - 1])
				{
					for (pListNode p2 = pnode; p2; p2 = p2->arr[k])
					{
						if (!p2->arr[k])
						{
							p2->arr[k] = p1;
							break;
						}

						if (p2->arr[k]->val<p1->val && p2->val > p1->val)
						{
							p1->arr[k] = p2->arr[k];
							p2->arr[k] = p1;
							break;
						}

						if (p2->val == p1->val)
							break;
					}
				}
			}
		}


		n = n / 2 - 1;
		k++;
		m *= 2;
	}
}

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值