详解Java中跳跃表的原理和实现

原文链接及讲解: 详解Java中跳跃表的原理和实现

java跳表实现

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * java跳表实现
 *
 * @author lyn
 * @date 2023/6/30 18:50
 */
public class OwnSkipList {
    private static final int MAX_LEVEL = 16;
    private static final float P = 0.5f;
    private static final int MAX_INT = 0x7fffffff;

    class Node {
        int val;
        Node[] forwards = new Node[MAX_LEVEL];
    }

    private Node head;
    private int curLevel;
    private Node[] upData;

    public OwnSkipList() {
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        curLevel = 0;
        head = getNewNode(-MAX_INT);
        upData = new Node[MAX_LEVEL];
        for (int i = 0; i < MAX_LEVEL; i++) {
            upData[i] = new Node();
        }
    }


    private Node getNewNode(int value) {
        Node node = new Node();
        for (int i = 0; i < MAX_LEVEL; i++) {
            node.forwards[i] = null;
        }
        node.val = value;
        return node;
    }

    /**
     * 插入元素
     *
     * @param value 值
     */
    public void insert(int value) {
        int lev = randomLevel();
        if (lev > curLevel) {
            curLevel = lev;
        }
        //寻找每层最接近的元素
        find(value);
        //创建一个新节点
        Node newNode = getNewNode(value);
        //插入操作
        for (int i = 0; i <= lev; i++) {
            newNode.forwards[i] = upData[i].forwards[i];
            upData[i].forwards[i] = newNode;
        }
    }

    public void delete(int value) {
        Node zeroLevelNode = find(value);
        //如果零层都没有,则结束
        if (zeroLevelNode.forwards[0] == null || zeroLevelNode.forwards[0].val != value) {
            return;
        }
        System.out.println("删除元素 " + value + "\n");
        // 删除操作
        for (int i = curLevel; i >= 0; i--) {
            if (upData[i].forwards[i] != null && upData[i].forwards[i].val == value) {
                upData[i].forwards[i] = upData[i].forwards[i].forwards[i];
            }
        }
        //删除空链
        while (curLevel > 0 && head.forwards[curLevel] == null) {
            curLevel--;
        }
    }

    /**
     * 查找最接近val的元素
     *
     * @param value 值
     */
    private Node find(int value) {
        Node tem = head;
        for (int i = curLevel; i >= 0; i--) {
            while (tem.forwards[i] != null && tem.forwards[i].val < value) {
                tem = tem.forwards[i];
            }
            //记录搜索过程中各级走过的最大节点位置
            upData[i] = tem;
        }
        return tem;
    }

    /**
     * 随机产生插入元素高度
     *
     * @return 高度
     */
    private int randomLevel() {
        int lev = 0;
        while (Math.random() < P && lev < MAX_LEVEL - 1) {
            lev++;
        }
        return lev;
    }

    public void print(int i) {
        // 遍历
        Node p = head.forwards[i];
        if (p == null) {
            return;
        }
        while (p != null) {
            System.out.printf("%d  ", p.val);
            p = p.forwards[i];
        }
        System.out.printf("\n");
    }

    /**
     * 遍历所有层
     */
    public void printAll() {
        for (int i = curLevel; i >= 0; i--) {
            System.out.printf("curLevel %d:  ", i);
            print(i);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        OwnSkipList skipList = new OwnSkipList();
        List<Integer> list = Stream.iterate(1, s -> s + 1).limit(50).collect(Collectors.toList());
        Collections.shuffle(list);
        for (Integer element : list) {
            skipList.insert(element);
        }
        skipList.printAll();

        skipList.delete(21);

        skipList.printAll();
    }
}
posted @ 2023-07-01 22:26  进击的小蔡鸟  阅读(137)  评论(0编辑  收藏  举报