Java实现数据结构跳表

package com.company.SkipList;

import java.util.Comparator;

@SuppressWarnings("all")
public class SkipList<K, V> {

  private int size;

  private static final int MAX_lEVEL = 32; // 节点的next节点的最高层数

  private static final double P = 0.25;

  private int level; // 实际的有效层数

  // 虚拟头结点 不存放任何的东西
  private Node<K, V> first;

  private Comparator<K> comparator;

  public SkipList(Comparator<K> comparator1) {
    first = new Node<K, V>(null, null, MAX_lEVEL);
    this.comparator = comparator1;
  }

  private int compare(K key1, K key2) {
    return comparator != null ? comparator.compare(key1, key2) : ((Comparable<K>) key1).compareTo(key2);
  }



  /**
   * @param key
   * @param value
   * @return
   * @throws IllegalAccessException 往跳表中加入键值对 prevs中存放前驱节点
   */
  public V put(K key, V value) throws IllegalAccessException {

    keyCheck(key);
    Node<K, V> node = first;
    Node<K, V>[] prevs = new Node[level];

    for (int i = level - 1; i >= 0; i--) {
      int cmp = -1;
      while (node.nexts[i] != null && (cmp = compare(key, node.nexts[i].key)) > 0) {
        node = node.nexts[i];
      }
      if (cmp == 0) {
        V oldValue = node.nexts[i].value;
        node.nexts[i].value = value;
        return oldValue;
      }
      prevs[i] = node;
    }

    // 添加新的结点
    int newlevel = randomLevel(); // 新层数
    Node<K, V> newNode = new Node<K, V>(key, value, newlevel);
    for (int i = 0; i < newlevel; i++) {

      if (i >= level) {
        first.nexts[i] = newNode;
      } else {
        newNode.nexts[i] = prevs[i].nexts[i]; // 新节点的next节点指向它的前驱节点以前指的方向
        prevs[i].nexts[i] = newNode; // 前驱节点的后继节点变为新节点
      }
    }
    size++;
    level = Math.max(newlevel, level);
    return value;

  }

  // 新节点的Nexts层数
  private int randomLevel() {
    int level = 1;
    while (Math.random() < P && level < MAX_lEVEL) {
      level++;
    }
    return level;
  }



  /**
   * @param key
   * @return 查找key对应的value
   * @throws IllegalAccessException 从最顶层的nexts数组开始,如果key比对应的key值大,则一直沿着这层向下搜索
   *                                如果key比对应的key值大,则进入下一层搜索 如果一样大了 就返回value值
   */
  public V get(K key) throws IllegalAccessException {
    keyCheck(key);
    Node<K, V> node = first;
    for (int i = level - 1; i >= 0; i--) {
      int cmp = -1;
      while (node.nexts[i] != null && (cmp = compare(key, node.nexts[i].key)) > 0) {
        node = node.nexts[i];
      }
      if (cmp == 0)
        return node.nexts[i].value;
    }
    return null;
  }



  /**
   * @param key
   * @return
   * @throws IllegalAccessException 删除目标节点
   */
  public V remove(K key) throws IllegalAccessException {
    keyCheck(key);
    Node<K, V> node = first;
    Node<K, V>[] prevs = new Node[level];
    boolean exist = false;
    for (int i = level - 1; i >= 0; i--) {
      int cmp = -1;
      while (node.nexts[i] != null && (cmp = compare(key, node.nexts[i].key)) > 0) {
        node = node.nexts[i];
      }
      if (cmp == 0) {
        exist = true;
      }
      prevs[i] = node;
    }
    // 添加新的结点
    if (!exist)
      return null;
    Node<K, V> removedNode = node.nexts[0];
    size--;
    for (int i = 0; i < removedNode.nexts.length; i++) {
      prevs[i].nexts[i] = removedNode.nexts[i];
    }

    // 更新跳表的层数
    int newLevel = level;
    while (--newLevel >= 0 && first.nexts[newLevel] == null) {
      level = newLevel;
    }

    return removedNode.value;
  }

  public boolean isEmpty() {
    return this.size == 0;
  }

  public int size() {
    return this.size;
  }

  private void keyCheck(K key) throws IllegalAccessException {
    if (key == null) {
      throw new IllegalAccessException("Key must not be empty!");
    }
  }

  private static class Node<K, V> {
    K key;
    V value;
    Node<K, V>[] nexts;

    public Node(K key, V value, int level) {
      this.key = key;
      this.value = value;
      this.nexts = new Node[level];
    }

    @Override
    public String toString() {
        return key + ":" + value + "_" + nexts.length;
    }
  }

  @Override
  public String toString() {
      StringBuilder sb = new StringBuilder();
      sb.append("一共" + level + "层").append("\n");
      for (int i = level - 1; i >= 0; i--) {
          Node<K, V> node = first;
          while (node.nexts[i] != null) {
              sb.append(node.nexts[i]);
              sb.append(" ");
              node = node.nexts[i];
          }
          sb.append("\n");
      }
      return sb.toString();
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值