跳躍表原理

 

跳躍表
node

 

跳錶是基於鏈表的,在鏈表的基礎上加了多層索引結構。dom

跳錶這種特殊的數據結果是有 Willam Pugh  發明的。最先出如今1990 年發表的論文《Skip Lists: A Probabilistic Alternative to Balanced Trees》ide

 

論文中有個描述:ui

 

  •  
  •  
Skip lists are a data structure that can be used in place of balanced trees.Skip lists use probabilistic balancing rather than strictly enforced balancing and as a result the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees.

 

簡單的說,跳錶是基於機率型的表。this

先看個普通有序鏈表的結構:spa

 

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

若是要查找  23 那麼起碼須要比較 2次,查找 43 比較 4次,查找 59 比較 6次。有什麼辦法解決這個問題呢?容易想到二分搜索。code

 

採用分層鏈表結構,以一些節點做爲索引,blog

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

好比,提取了 14  34 50 72 做爲一層鏈表,查找 59 的時候,就能夠經過比較 14 24 50 59 共5次找到 59 來減小查找次數。索引

若是加一層,基本上就能夠採用相似二分的方式進行查找了圖片

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

 

如今看給完整的 快表插入一個新元素的過程:

 

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=圖片

參考代碼:

public class SkipList {
    private static class SkipListNode {
        int data;

        SkipListNode[] next;

        SkipListNode(int d, int level) {
            data = d;
            next = new SkipListNode[level + 1];
        }
    }

    private int maxLevel;

    SkipListNode header;

    private static final int INFINITY = Integer.MAX_VALUE;

    SkipList(int maxLevel) {
        this.maxLevel = maxLevel;
        header = new SkipListNode(0, maxLevel);
        SkipListNode sentinel = new SkipListNode(INFINITY, maxLevel);
        for (int i = 0; i <= maxLevel; i++)
            header.next[i] = sentinel;
    }

    public boolean find(int key) {
        SkipListNode current = header;

        for (int i = maxLevel; i >= 0; i--) {
            SkipListNode next = current.next[i];
            while (next.data < key) {
                current = next;
                next = current.next[i];
            }
        }
        current = current.next[0];

        if (current.data == key)
            return true;
        else
            return false;
    }

    public void insert(int searchKey, int newValue) {
        SkipListNode[] update = new SkipListNode[maxLevel + 1];
        SkipListNode current = header;

        for (int i = maxLevel; i >= 0; i--) {
            SkipListNode next = current.next[i];
            while (next.data < searchKey) {
                current = next;
                next = current.next[i];
            }
            update[i] = current;
        }
        current = current.next[0];
        if (current.data == searchKey)
            current.data = newValue;
        else {
            int v = generateRandomLevel();
            SkipListNode node = new SkipListNode(newValue, maxLevel);
            for (int i = 0; i <= v; i++) {
                node.next[i] = update[i].next[i];
                update[i].next[i] = node;
            }
            update = null;
        }
    }

    private int generateRandomLevel() {
        int newLevel = 0;
        while (newLevel < maxLevel && Math.random() < 0.5)
            newLevel++;
        return newLevel;
    }

    public boolean delete(int searchKey) {
        SkipListNode[] update = new SkipListNode[maxLevel + 1];
        SkipListNode current = header;
        for (int i = maxLevel; i >= 0; i--) {
            SkipListNode next = current.next[i];
            while (next.data < searchKey) {
                current = next;
                next = current.next[i];
            }
            update[i] = current;
        }
        current = current.next[0];
        if (current.data == searchKey) {
            for (int i = 0; i <= maxLevel; i++) {
                if (update[i].next[i] == current) {
                    update[i].next[i] = current.next[i];
                    current.next[i] = null;
                } else
                    current.next[i] = null;
            }

            return true;
        }

        return false;
    }

    public static void main(String[] args) {

    }
}

https://mp.weixin.qq.com/s/Ks8FMqi4faBAuaUYb3uu6g

相關文章
相關標籤/搜索