漫画:什么是 “跳表” ?

    实现代码:

    1. public class SkipList{
    2. //结点“晋升”的概率
    3. private static final double PROMOTE_RATE = 0.5;
    4. private Node head,tail;
    5. private int maxLevel;
    6. public SkipList() {
    7. head = new Node(Integer.MIN_VALUE);
    8. tail = new Node(Integer.MAX_VALUE);
    9. head.right = tail;
    10. tail.left = head;
    11. }
    12. //查找结点
    13. public Node search(int data){
    14. Node p= findNode(data);
    15. if(p.data == data){
    16. System.out.println("找到结点:" + data);
    17. return p;
    18. }
    19. System.out.println("未找到结点:" + data);
    20. return null;
    21. }
    22. //找到值对应的前置结点
    23. private Node findNode(int data){
    24. Node node = head;
    25. while(true){
    26. while (node.right.data!=Integer.MAX_VALUE && node.right.data<=data) {
    27. node = node.right;
    28. }
    29. if (node.down == null) {
    30. break;
    31. }
    32. node = node.down;
    33. }
    34. return node;
    35. }
    36. //插入结点
    37. public void insert(int data){
    38. Node preNode= findNode(data);
    39. //如果data相同,直接返回
    40. if (preNode.data == data) {
    41. return;
    42. }
    43. Node node=new Node(data);
    44. appendNode(preNode, node);
    45. int currentLevel=0;
    46. //随机决定结点是否“晋升”
    47. Random random = new Random();
    48. while (random.nextDouble() < PROMOTE_RATE) {
    49. //如果当前层已经是最高层,需要增加一层
    50. if (currentLevel == maxLevel) {
    51. addLevel();
    52. }
    53. //找到上一层的前置节点
    54. while (preNode.up==null) {
    55. preNode=preNode.left;
    56. }
    57. preNode=preNode.up;
    58. //把“晋升”的新结点插入到上一层
    59. Node upperNode = new Node(data);
    60. appendNode(preNode, upperNode);
    61. upperNode.down = node;
    62. node.up = upperNode;
    63. node = upperNode;
    64. currentLevel++;
    65. }
    66. }
    67. //在前置结点后面添加新结点
    68. private void appendNode(Node preNode, Node newNode){
    69. newNode.left=preNode;
    70. newNode.right=preNode.right;
    71. preNode.right.left=newNode;
    72. preNode.right=newNode;
    73. }
    74. //增加一层
    75. private void addLevel(){
    76. maxLevel++;
    77. Node p1=new Node(Integer.MIN_VALUE);
    78. Node p2=new Node(Integer.MAX_VALUE);
    79. p1.right=p2;
    80. p2.left=p1;
    81. p1.down=head;
    82. head.up=p1;
    83. p2.down=tail;
    84. tail.up=p2;
    85. head=p1;
    86. tail=p2;
    87. }
    88. //删除结点
    89. public boolean remove(int data){
    90. Node removedNode = search(data);
    91. if(removedNode == null){
    92. return false;
    93. }
    94. int currentLevel=0;
    95. while (removedNode != null){
    96. removedNode.right.left = removedNode.left;
    97. removedNode.left.right = removedNode.right;
    98. //如果不是最底层,且只有无穷小和无穷大结点,删除该层
    99. if(currentLevel != 0 && removedNode.left.data == Integer.MIN_VALUE && removedNode.right.data == Integer.MAX_VALUE){
    100. removeLevel(removedNode.left);
    101. }else {
    102. currentLevel ++;
    103. }
    104. removedNode = removedNode.up;
    105. }
    106. return true;
    107. }
    108. //删除一层
    109. private void removeLevel(Node leftNode){
    110. Node rightNode = leftNode.right;
    111. //如果删除层是最高层
    112. if(leftNode.up == null){
    113. leftNode.down.up = null;
    114. rightNode.down.up = null;
    115. }else {
    116. leftNode.up.down = leftNode.down;
    117. leftNode.down.up = leftNode.up;
    118. rightNode.up.down = rightNode.down;
    119. rightNode.down.up = rightNode.up;
    120. }
    121. maxLevel --;
    122. }
    123. //输出底层链表
    124. public void printList() {
    125. Node node=head;
    126. while (node.down != null) {
    127. node = node.down;
    128. }
    129. while (node.right.data != Integer.MAX_VALUE) {
    130. System.out.print(node.right.data + " ");
    131. node = node.right;
    132. }
    133. System.out.println();
    134. }
    135. //链表结点类
    136. public class Node {
    137. public int data;
    138. //跳表结点的前后和上下都有指针
    139. public Node up, down, left, right;
    140. public Node(int data) {
    141. this.data = data;
    142. }
    143. }
    144. public static void main(String[] args) {
    145. SkipList list=new SkipList();
    146. list.insert(50);
    147. list.insert(15);
    148. list.insert(13);
    149. list.insert(20);
    150. list.insert(100);
    151. list.insert(75);
    152. list.insert(99);
    153. list.insert(76);
    154. list.insert(83);
    155. list.insert(65);
    156. list.printList();
    157. list.search(50);
    158. list.remove(50);
    159. list.search(50);
    160. }
    161. }