返回
数据结构入门:跳表实现指南
后端
2023-12-03 14:29:21
跳表简介
跳表是一种高效的链表数据结构,它通过引入多个层次的指针(称为跳跃指针)来优化搜索和插入操作。这些跳跃指针允许快速跳过链表中的多个元素,从而缩短了查找和插入的时间。跳表在实际应用中非常有用,例如数据库和分布式系统。
LeetCode 1206 题解
LeetCode 1206 题要求我们实现一个跳表数据结构。以下是如何使用 Java 实现此跳表:
import java.util.Random;
class Skiplist {
private static final double P = 0.5;
private Node head, tail;
private int level, size;
private Random random;
public Skiplist() {
head = new Node(Integer.MIN_VALUE, Integer.MAX_VALUE, 0);
tail = new Node(Integer.MAX_VALUE, Integer.MAX_VALUE, 0);
for (int i = 0; i < head.nexts.length; i++) {
head.nexts[i] = tail;
}
level = 0;
size = 0;
random = new Random();
}
public boolean search(int target) {
Node curr = head;
for (int i = level - 1; i >= 0; i--) {
while (curr.nexts[i].val < target) {
curr = curr.nexts[i];
}
}
curr = curr.nexts[0];
return curr.val == target;
}
public void add(int num) {
int newLevel = randomLevel();
level = Math.max(level, newLevel);
Node newNode = new Node(num, new int[newLevel]);
for (int i = 0; i < newLevel; i++) {
newNode.nexts[i] = findNext(i, num);
findPrev(i, num).nexts[i] = newNode;
}
size++;
}
public boolean erase(int num) {
Node curr = head;
boolean removed = false;
for (int i = level - 1; i >= 0; i--) {
while (curr.nexts[i].val < num) {
curr = curr.nexts[i];
}
if (curr.nexts[i].val == num) {
removed = true;
curr.nexts[i] = curr.nexts[i].nexts[i];
if (i == level - 1 && curr.nexts[i] == tail) {
level--;
}
}
}
if (removed) {
size--;
}
return removed;
}
private int randomLevel() {
int lvl = 1;
while (random.nextDouble() < P && lvl < 32) {
lvl++;
}
return lvl;
}
private Node findPrev(int level, int num) {
Node curr = head;
while (curr.nexts[level].val < num) {
curr = curr.nexts[level];
}
return curr;
}
private Node findNext(int level, int num) {
Node curr = head;
while (curr.nexts[level] != null && curr.nexts[level].val <= num) {
curr = curr.nexts[level];
}
return curr.nexts[level];
}
private static class Node {
int val;
int[] nexts;
public Node(int val, int maxLevel) {
this.val = val;
nexts = new int[maxLevel];
}
public Node(int val, int[] nexts) {
this.val = val;
this.nexts = nexts;
}
}
}
理解关键实现细节
- 层级结构: 跳表使用多个层次的指针(称为跳跃指针)来实现快速搜索。
- 随机层级: 新节点的层级数是随机生成的,以达到平均 O(log n) 的时间复杂度。
- 搜索和插入: 使用跳跃指针进行搜索和插入,可以快速跳过链表中的多个元素。
- 删除: 删除节点时,需要更新所有受影响的跳跃指针。
总结
跳表是一种强大的数据结构,它结合了链表的简单性和树的快速搜索能力。通过理解跳表的概念和实现细节,你可以提升自己的算法技能,在实际应用中有效解决复杂的数据处理问题。