跳表java代码实现,根据左神视频改进

跳表的具体插入、删除过程,网上都有的,大家可以自行查阅。
下面是观看左神算法之后,自己实现的code。
欢迎大家批评指正。

import java.util.ArrayList;

public class SkipListTest {
    public static void main(String[] args) {
        SkipList list = new SkipList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        System.out.println(list.size());
        list.remove(2);
        System.out.println(list.size());
        System.out.println(list.contains(3));
        System.out.println(list.contains(2));
        System.out.println(list.getHead().value);
    }
}

class SkipListNode {
    /**
     * 因为head的value放的是null,所以要用Integer类型
     * value值是不会重复的
     */
    public Integer value;
    public ArrayList<SkipListNode> nextNodes;

    public SkipListNode(Integer value) {
        this.value = value;
        this.nextNodes = new ArrayList<>();
    }
}

class SkipList {
    private int maxLevel;
    private int size;
    private SkipListNode head;
    private static final double CHANCE = 0.5;

    public SkipList() {
        // 一开始只产生到第0层
        maxLevel = 0;

        // head不算在size中
        size = 0;

        // head中数值为null
        head = new SkipListNode(null);

        // head的层数随maxLevel更新,第0层也算一层,所以head要在第0层留个后
        head.nextNodes.add(null);
    }

    public SkipListNode getHead() {
        return head;
    }

    /**
     * 添加值进SkipList
     * @param aimValue  要添加的值
     */
    public void add(Integer aimValue) {
        if (aimValue == null) {
            return;
        }

        // 先更新size
        size++;

        // 产生新值的层数
        int level = 0;
        while (Math.random() < CHANCE) {
            level++;
        }

        // 更新maxLevel以及head的层数
        while (maxLevel < level) {
            maxLevel++;
            head.nextNodes.add(null);
        }

        int val = maxLevel;
        SkipListNode curNode = head;

        // 若最大层数大于本节点的层数,从最高层开始找<=aimValue的最大值,高层好找
        // 找的是maxLevel到level+1层的
        while (val > level) {
            curNode = findNext(aimValue, curNode, val);
            val--;
        }

        SkipListNode newNode = new SkipListNode(aimValue);

        // 从第level层到第0层,每一层中将值添加进去
        while (level >= 0) {
            curNode = findNext(aimValue, curNode, level);

            // 这两个顺序不能反,反了就是newNode自己指向自己了
            newNode.nextNodes.add(0, curNode.nextNodes.get(level));
            curNode.nextNodes.set(level, newNode);
            level--;
        }
    }

    /**
     * 从curNode开始,在level这层找到<=aimValue的最大值,大于的之前的那个
     */
    private SkipListNode findNext(Integer aimValue, SkipListNode curNode, int level) {
        // 用nextNode的值与aimValue进行比较
        SkipListNode nextNode = curNode.nextNodes.get(level);
        while (nextNode != null) {
            if (aimValue.compareTo(nextNode.value) < 0) {
                break;
            }
            curNode = nextNode;
            nextNode = curNode.nextNodes.get(level);
        }
        return curNode;
    }

    public int size() {
        return size;
    }

    /**
     * SkipList中是否含aimValue这个值
     */
    public boolean contains(Integer aimValue) {
        SkipListNode node = find(aimValue);
        return node != null && node.value != null && node.value.compareTo(aimValue) == 0;
    }

    /**
     * 在整个SkipList中找到<=value的最大值,不一定是在最底层才找到
     */
    private SkipListNode find(Integer value) {
        return find(value, head, maxLevel);
    }

    private SkipListNode find(Integer aimValue, SkipListNode curNode, int level) {
        while (level >= 0) {
            curNode = findNext(aimValue, curNode, level);
            // curNode.value可能为null,head的value便为null
            if (curNode.value != null && curNode.value.compareTo(aimValue) == 0) {
                break;
            }
            level--;
        }
        return curNode;
    }

    public void remove(Integer aimValue) {
        if (!contains(aimValue)) {
            return;
        }

        size--;
        SkipListNode aimNode = find(aimValue);
        int level = maxLevel;
        SkipListNode curNode = head;

        // 该节点的所有层的连接都要移除
        while (level >= 0) {
            // 第maxLevel层到第aimNode.nextNodes.size()层走这部分
            if (level >= aimNode.nextNodes.size()) {
                curNode = findNext(aimValue, curNode, level--);
                continue;
            }

            // 第aimNode.nextNodes.size()-1层到第0层走下半部分
            // 找到aimNode的前沿节点curNode
            while (curNode.nextNodes.get(level).value.compareTo(aimValue) != 0) {
                curNode = curNode.nextNodes.get(level);
            }
            curNode.nextNodes.set(level, aimNode.nextNodes.get(level));
            level--;
        }

        // 更新maxLevel与head的nextNodes,head第0层的nextNode要保留一个
        while (maxLevel > 0 && head.nextNodes.get(maxLevel) == null) {
            head.nextNodes.remove(maxLevel);
            maxLevel--;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值