聊聊跳表?

跳表是一种数据结构,通过多级索引实现快速查询、插入和删除,时间复杂度为O(logn)。Java中的ConcurrentSkipListMap利用跳表实现高并发下的有序Map操作,其内部由Node和Index节点组成,保证线程安全并提供高效性能。
摘要由CSDN通过智能技术生成

什么是跳表

跳表(Skip List)是一种类似于链表的数据结构,其查询、插入、删除的时间复杂度都是O(logn)。

在传统的单链表结构中,查找某个元素需要从链表的头部按顺序遍历,直到找到目标元素为止,查找的时间复杂度为O(n)。
而跳表结合了树和跳表的特点,其特性如下:

  • 跳表由很多层组成;
  • 每一层都是一个有序的链表;
  • 最底层的链表包含所有元素;
  • 对于每一层的任意一个节点,不仅有指向其下一个节点的指针,也有指向其下一层的指针;
  • 如果一个元素出现Level n层的链表中,则它在Level n层以下的链表也都会出现。

核心思想

  • 第一层(最底层)上有N个节点,即所有节点都存在于第一层上;
  • 高度随机决定,扔硬币问题,0.5的概率为正面,0.5的概率为反面,抛出正面则层数加一,即高度加一;
  • 第一层有N个节点,第二层以0.5的概率扔硬币,所以第二层有N/2个,同理第三层有N/4,一次类推,所以当有N个节点的时候,形成跳表结构,需要logN次,跟输入规律没关系,跟概率有关系,但是概率问题也能logN。
  • 从最高层一次往下找,高链表上跨一个节点,底下不知道跨了多少个节点,这就是跳表的好处。

跳表实际上是一种空间换时间的数据结构

ConcurrentSkipListMap:java中的跳表

ConcurrentSkipListMap是在JDK1.6中新增的,为了对高并发场景下的有序Map提供很好的支持,它有几个特点:

  • 高并发场景
  • key是有序的
  • 添加、删除、查找操作都是基于跳表结构(Skip List)实现的
  • key和value都不能为null

ConcurrentSkipListMap结构

  • Node节点代表了真正存储数据的节点,包含了key、value、指向下一个节点的指针next:
static final class Node<K,V> {
   final K key;
   volatile Object value;
   volatile Node<K,V> next;

   /**
    * Creates a new regular node.
    */
   Node(K key, Object value, Node<K,V> next) {
       this.key = key;
       this.value = value;
       this.next = next;
   }
}
  • Index节点代表了跳表的层级,包含了当前节点node、下一层down、当前层的下一个节点right
static class Index<K,V> {
   final Node<K,V> node;
   final Index<K,V> down;
   volatile Index<K,V> right;

   /**
    * Creates index node with given values.
    */
   Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
       this.node = node;
       this.down = down;
       this.right = right;
   }
}

如图所示,Node节点将真实的数据按顺序链接起来,Index节点组成了条表中多层次的索引结构
在这里插入图片描述## 案例

public class ConcurrentSkipListMapDemo {
    public static void main(String[] args) {
        ConcurrentSkipListMap<Integer, String> skipListMap = new ConcurrentSkipListMap<>();
        skipListMap.put(4, "4");
        skipListMap.put(5, "5");
        skipListMap.put(1, "1");
        skipListMap.put(6, "6");
        skipListMap.put(2, "2");

        System.out.println(skipListMap.keySet());
        System.out.println(skipListMap);
        System.out.println(skipListMap.descendingKeySet());
        System.out.println(skipListMap.descendingMap());
    }
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值