增長了向前指針的鏈表叫做跳錶。跳錶全稱叫作跳躍表,簡稱跳錶。跳錶是一個隨機化的數據結構,實質就是一種能夠進行二分查找的有序鏈表。跳錶在原有的有序鏈表上面增長了多級索引,經過索引來實現快速查找。跳錶不只能提升搜索性能,同時也能夠提升插入和刪除操做的性能。java
1.由不少層結構組成
2.每一層都是一個有序的鏈表
3.最底層(第一層)的鏈表包含全部元素
4.若是一個元素出如今 第 i 層 的鏈表中,則它在第 i 層 之下的鏈表也都會出現。
5.每一個節點包含兩個指針,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素。node
栗子:查找元素 6
1.頭指針最開始在第一層最小值INT_MIN處
2.因而和旁邊的1比較,固然了1大嘛,因而指針移向1
3.再和當前層4比較, 比 4 大,跳到4
4.與7比較,比7小,因而向下跳到第二層4
5..與5比較,比5大,跳到5
6.與7比較,比7小,跳到最低層5
7.只能依次向後比較了,因而找到了6git
1.節點定義,共三個成員變量:value,right,downgithub
package crabapple; /* * Copyright (c) This is zhaoxubin's Java program. * Copyright belongs to the crabapple organization. * The crabapple organization has all rights to this program. * No individual or organization can refer to or reproduce this program without permission. * If you need to reprint or quote, please post it to zhaoxubin2016@live.com. * You will get a reply within a week, * */ import java.util.Random; /** * 節點類定義 */ class Node { //值 public int value = 0; //當前層下一個節點 public Node right; //下一層,直連的節點 public Node down; //構造函數 public Node() { } public Node(int value) { this.value = value; } }
2.跳錶類 定義,你們能夠清晰的看請代碼邏輯結構,該類只暴露insert()和search()兩個方法,其它變量及方法均設爲私有.數據結構
/** * 跳錶定義 */ public class SkipTable { //表層數 private int levelCount; //表的頭指針 private Node firstNode; //初始化:層數爲1,共先後兩個節點,一個最小值,一個最大值 private void init() { levelCount = 1; firstNode=new Node(); firstNode.value = Integer.MIN_VALUE; firstNode.right = new Node(Integer.MAX_VALUE); } public SkipTable() { init(); } /** * 查找值 * @param value * @return */ public boolean search(int value) { Node current = firstNode; return toSearch(current, value); } private boolean toSearch(Node node, int value) { if (node.value == value) return true; else if (node.right!=null&&value >= node.right.value) return toSearch(node.right, value); else if (node.down != null) return toSearch(node.down, value); return false; } /** * 插入值 * @param value * @return */ public boolean insert(int value) { //判斷是否有這個元素 if (search(value)) return false; //隨機獲取一個層數 int willLevel = updateLevelCount(); //判斷是否添加新層 if (willLevel > levelCount) { Node newFirstNode = new Node(); addLevel(firstNode, newFirstNode); firstNode=newFirstNode; levelCount = willLevel; } //插入新元素 Node port = firstNode; int skipLevel = levelCount - willLevel; //迭代到指定層 while ((skipLevel--) > 0) port = port.down; //上下層新節點的橋樑 Node insertNode = null; while (port != null) { //獲取當前層第一個節點指針 Node curPort = port; //迭代到右邊的節點值比本身大爲止 while (port.right.value < value) port = port.right; //準備插入的新節點 Node curInNode = new Node(value); //更新當前節點和前節點指針指向 curInNode.right = port.right; port.right = curInNode; //將當前節點引用給上層節點 if (insertNode != null) insertNode.down = curInNode; //將新插入的節點指針更新到insertNode,以備在下一層創建指向 insertNode = curInNode; //行頭指針向下迭代 port = port.down; } return true; } /** * 添加新層 * * @param oldFirst * @param newFirst */ private void addLevel(Node oldFirst, Node newFirst) { newFirst.value = oldFirst.value; newFirst.down = oldFirst; if (oldFirst.right != null) { Node newRightNode = new Node(); newFirst.right = newRightNode; addLevel(oldFirst.right, newRightNode); } } /** * 以必定機率使得獲取一個和老層數差值不超過1的新層數 * @return */ private int updateLevelCount() { Random random=new Random(); int v = random.nextInt(10); return v ==0 ? random.nextInt(levelCount) + 2 : random.nextInt(levelCount)+1 ; } }
3.測試類app
package crabapple; public class Main { public static void main(String[] args) { //測試 SkipTable skipTable=new SkipTable(); skipTable.insert(1); skipTable.insert(2); skipTable.insert(3); skipTable.insert(4); skipTable.insert(5); skipTable.insert(6); skipTable.insert(7); skipTable.insert(8); skipTable.insert(9); skipTable.insert(10); //健壯性邊界值測試 System.out.println(skipTable.search(0)); System.out.println(skipTable.search(1)); System.out.println(skipTable.search(2)); System.out.println(skipTable.search(5)); System.out.println(skipTable.search(9)); System.out.println(skipTable.search(10)); System.out.println(skipTable.search(11)); } } //output: /** * false * true * true * true * true * true * false * * Process finished with exit code 0 */
上面的代碼,你們是能夠直接運行,筆者能力有限,代碼也許還有不足,望你們多多指教.dom