假如我们要使用某种数据结构来维护一组有序的int型数据的集合, 并希望这个数据结构在插入、删除、查找等操作上能够尽可能快速,那么,就可以使用跳跃表。
1 package 跳跃表; 2 3 //节点 4 class Node { 5 int value = -1; 6 int level;// 跨越几层 7 Node[] next;// 指向下一个节点 8 9 public Node(int value, int level) { 10 this.value = value; 11 this.level = level; 12 this.next = new Node[level]; 13 } 14 } 15 16 //跳跃表 17 public class SkipList { 18 // 允许的最大层数 19 int maxLevel = 16; 20 // 头节点,充当辅助。 21 Node head = new Node(-1, 16); 22 // 当前跳跃表节点的个数 23 int size = 0; 24 // 当前跳跃表的层数,初始化为1层。 25 int levelCount = 1; 26 27 public Node find(int value) { 28 Node temp = head; 29 for (int i = levelCount - 1; i >= 0; i--) { 30 while (temp.next[i] != null && temp.next[i].value < value) { 31 temp = temp.next[i]; 32 } 33 } 34 // 判断是否有该元素存在 35 if (temp.next[0] != null && temp.next[0].value == value) { 36 System.out.println(value + " 查找成功"); 37 return temp.next[0]; 38 } else { 39 return null; 40 } 41 } 42 43 // 为了方便,跳跃表在插入的时候,插入的节点在当前跳跃表是不存在的 44 // 不允许插入重复数值的节点。 45 public void insert(int value) { 46 int level = getLevel(); 47 Node newNode = new Node(value, level); 48 // update用于记录要插入节点的前驱 49 Node[] update = new Node[level]; 50 51 Node temp = head; 52 for (int i = level - 1; i >= 0; i--) { 53 while (temp.next[i] != null && temp.next[i].value < value) { 54 temp = temp.next[i]; 55 } 56 update[i] = temp; 57 } 58 // 把插入节点的每一层连接起来 59 for (int i = 0; i < level; i++) { 60 newNode.next[i] = update[i].next[i]; 61 update[i].next[i] = newNode; 62 } 63 // 判断是否需要更新跳跃表的层数 64 if (level > levelCount) { 65 levelCount = level; 66 } 67 size++; 68 System.out.println(value + " 插入成功"); 69 } 70 71 public void delete(int value) { 72 Node[] update = new Node[levelCount]; 73 Node temp = head; 74 75 for (int i = levelCount - 1; i >= 0; i--) { 76 while (temp.next[i] != null && temp.next[i].value < value) { 77 temp = temp.next[i]; 78 } 79 update[i] = temp; 80 } 81 82 if (temp.next[0] != null && temp.next[0].value == value) { 83 size--; 84 System.out.println(value + " 删除成功"); 85 for (int i = levelCount - 1; i >= 0; i--) { 86 if (update[i].next[i] != null && update[i].next[i].value == value) { 87 update[i].next[i] = update[i].next[i].next[i]; 88 } 89 } 90 } 91 } 92 93 // 打印所有节点 94 public void printAllNode() { 95 Node temp = head; 96 while (temp.next[0] != null) { 97 System.out.println(temp.next[0].value + " "); 98 temp = temp.next[0]; 99 } 100 } 101 102 // 模拟抛硬币 103 private int getLevel() { 104 int level = 1; 105 while (true) { 106 int t = (int) (Math.random() * 100); 107 if (t % 2 == 0) { 108 level++; 109 } else { 110 break; 111 } 112 } 113 System.out.println("当前的level = " + level); 114 return level; 115 } 116 117 // 测试数据 118 public static void main(String[] args) { 119 SkipList list = new SkipList(); 120 for (int i = 0; i < 6; i++) { 121 list.insert(i); 122 } 123 list.printAllNode(); 124 list.delete(4); 125 list.printAllNode(); 126 System.out.println(list.find(3)); 127 System.out.println(list.size + " " + list.levelCount); 128 } 129 }
运行结果如下:
当前的level = 1 0 插入成功 当前的level = 1 1 插入成功 当前的level = 5 2 插入成功 当前的level = 1 3 插入成功 当前的level = 3 4 插入成功 当前的level = 2 5 插入成功 0 1 2 3 4 5 4 删除成功 0 1 2 3 5 3 查找成功 跳跃表.Node@707f7052 5 5