跳跃表:
跳跃表(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;
}
}