跳表Java实现

跳跃表是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间),并且对并发算法友好。
跳跃表的应用
Skip list(跳表)是一种可以代替平衡树的数据结构,默认是按照Key值升序的。Skip list让已排序的数据分布在多层链表中,以0-1随机数决定一个数据的向上攀升与否,通过“空间来换取时间”的一个算法,在每个节点中增加了向前的指针,在插入、删除、查找时可以忽略一些不可能涉及到的结点,从而提高了效率。
在Java的API中已经有了实现:分别是
ConcurrentSkipListMap(在功能上对应HashTable、HashMap、TreeMap) ;
ConcurrentSkipListSet(在功能上对应HashSet).
确切来说,SkipList更像Java中的TreeMap,TreeMap基于红黑树(一种自平衡二叉查找树)实现的,时间复杂度平均能达到O(log n)。
HashMap是基于散列表实现的,时间复杂度平均能达到O(1)。ConcurrentSkipListMap是基于跳表实现的,时间复杂度平均能达到O(log n)。
Skip list的性质
(1) 由很多层结构组成,level是通过一定的概率随机产生的。
(2) 每一层都是一个有序的链表,默认是升序
(3) 最底层(Level 1)的链表包含所有元素。
(4) 如果一个元素出现在Level i 的链表中,则它在Level i 之下的链表也都会出现。
(5) 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素。

复杂度分析:
跳表Java实现_第1张图片

package com.gloomy.Tree;

import java.util.Random;

/**
 * 跳表
 * 
 * @author 过路的守望
 *
 */
public class SkipList<E extends Comparablesuper E>> {

    /*
     * 跳表层数32层: 定义成32层理论上对于2^32-1个元素的查询最优。
     */
    private final int MAX_LEVEL = 32;
    /*
     * 当前跳表的有效层
     */
    private int level = 0;
    /*
     * 跳表的头部节点
     */
    private final SkipNode Header = new SkipNode(MAX_LEVEL, null);
    /*
     * 随机数发生器
     */
    private final Random random = new Random();
    /*
     * 自然数e
     */
    private final double E = Math.E;

    /**
     * 检查跳表中是否包含val节点
     * 
     * @param node
     * @return
     */
    public boolean contains(E val) {
        /*
         * cur指向跳表头结点
         */
        SkipNode cur = Header;
        /*
         * 从顶层开始查找当前层的链表中是否包含节点node,如果包含node节点,直接返回true;否则在下一层中查找是否包含node节点。
         * 如果最底层的链表也不包含node节点,则放回false。
         */
        for (int i = level; i >= 0; i--) {
            while (cur.next != null && cur.next[i].val.compareTo(val) < 0) {
                cur = cur.next[i];
            }
            if (cur.next[i].val.equals(val)) {
                return true;
            }
        }
        return false;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void insert(E val) {
        SkipNode cur = Header;
        SkipNode[] predecessors = new SkipNode[MAX_LEVEL];
        /*
         * 找出每层中待插入节点的前继节点
         */
        for (int i = level; i >= 0; i--) {
            cur = Header;
            while (cur.next[i] != null && cur.next[i].val.compareTo(val) < 0) {
                cur = cur.next[i];
            }
            predecessors[i] = cur;
        }
        cur = cur.next[0];
        int nextLevel = randomLevel();
        /*
         * 如果带插入节点位置是空的或者与node节点值不同 将新节点插入到跳表中
         */
        if (cur == null || !cur.val.equals(val)) {
            /*
             * 若新增一层链表
             */
            if (nextLevel > level) {
                predecessors[nextLevel] = Header;
                level = nextLevel;
            }
            SkipNode node = new SkipNode(MAX_LEVEL, val);
            for (int i = level; i >= 0; i--) {
                node.next[i] = predecessors[i].next[i];
                predecessors[i].next[i] = node;
            }
        }
    }

    @SuppressWarnings({ "unchecked" })
    public void delete(E val) {
        SkipNode cur = Header;
        SkipNode[] predecessors = new SkipNode[MAX_LEVEL];
        /*
         * 寻找待删除元素在不同层上的前继节点
         */
        for (int i = level; i >= 0; i--) {
            while (cur.next != null && cur.next[i].val.compareTo(val) < 0) {
                cur = cur.next[i];
            }
            predecessors[i] = cur;
        }
        cur = cur.next[0];
        /*
         * 跳表中不含此节点
         */
        if (!cur.val.equals(val)) {
            return;
        }
        for (int i = level; i >= 0; i--) {
            if (!predecessors[i].next[i].val.equals(val)) {
                continue;
            }
            predecessors[i].next[i] = cur.next[i];
        }
        /*
         * 如果删除元素val后level层元素数目为0,层数减少一层
         */
        while (level > 0 && Header.next[level] == null) {
            level--;
        }

    }

    /**
     * 输出跳表中的元素
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        SkipNode cur = Header.next[0];
        sb.append("{");
        while (cur.next[0] != null) {
            sb.append(cur.val);
            sb.append(",");
            cur = cur.next[0];
        }
        sb.append(cur.val);
        sb.append("}");
        return sb.toString();
    }

    /**
     * 利用随机数发生器来决定是否新增一层
     * 
     * @return
     */
    private int randomLevel() {
        double ins = random.nextDouble();
        int nextLevel = level;
        if (ins > E && level < MAX_LEVEL) {
            nextLevel++;
        }
        return nextLevel;
    }

}

class SkipNode<E extends Comparablesuper E>> {
    /*
     * 节点存储的值Val
     */
    public E val;
    /*
     * 节点指向第i层的节点next[i]
     */
    public SkipNode[] next;

    @SuppressWarnings("unchecked")
    public SkipNode(int MAX_LEVEL, E val) {
        this.next = new SkipNode[MAX_LEVEL];
        this.val = val;
    }
}

你可能感兴趣的:(数据结构)