成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Redis跳躍表如何添加元素?

數(shù)據(jù)庫 Redis
跳躍表是由多個有序的鏈表組成的,最底層存儲了所有元素的數(shù)據(jù),這樣存儲讓它的查詢效率更高,查詢復雜度從 O(n) 變?yōu)榱?O(log n)。

今天分享的這道題來自于蔚來的真實面試題。

面試 Java 不可能不問 Redis,問到 Redis 不可能不問 Redis 的常用數(shù)據(jù)類型,問到 Redis 的常用數(shù)據(jù)類型,不可能不問跳躍表,當問到跳躍表經(jīng)常會被問到跳躍表的查詢和添加流程,所以接下來我們一起來看這道題的答案吧。

Redis 有序集合ZSet 是由 ziplist (壓縮列表) 或 skiplist (跳躍表) 組成的。

  1. 壓縮列表 ziplist 本質上就是一個字節(jié)數(shù)組,是 Redis 為了節(jié)約內存而設計的一種線性數(shù)據(jù)結構,可以包含多個元素,每個元素可以是一個字節(jié)數(shù)組或一個整數(shù)。
  2. 跳躍表 skiplist 是一種有序數(shù)據(jù)結構,它通過在每個節(jié)點中維持多個指向其他節(jié)點的指針,從而達到快速訪問節(jié)點的目的。跳躍表支持平均 O(logN)、最壞 O(N) 復雜度的節(jié)點查找,還可以通過順序性操作來批量處理節(jié)點。

跳躍表介紹

跳躍表 Skip List,也稱之為跳表,是一種數(shù)據(jù)結構,用于在有序元素的集合中進行高效的查找操作。它通過添加多層鏈表的方式,提供了一種以空間換時間的方式來加速查找。

跳躍表由一個帶有多層節(jié)點的鏈表組成,每一層都是原始鏈表的一個子集。最底層是一個完整的有序鏈表,包含所有元素。每個更高層級都是下層級的子集,通過添加額外的指針來跳過一些元素。這些額外的指針稱為“跳躍指針”,它們允許快速訪問更遠的節(jié)點,從而減少了查找所需的比較次數(shù)。

跳躍表的平均查找時間復雜度為 O(log n),其中 n 是元素的數(shù)量。這使得它比普通的有序鏈表具有更快的查找性能,并且與平衡二叉搜索樹(如紅黑樹)相比,實現(xiàn)起來更為簡單。

簡單的跳躍表如下圖所示:

跳躍表添加流程

前置知識:節(jié)點隨機層數(shù)

在開始講跳躍表的添加流程之前,必須先搞懂一個概念:節(jié)點的隨機層數(shù)。所謂的隨機層數(shù)指的是每次添加節(jié)點之前,會先生成當前節(jié)點的隨機層數(shù),根據(jù)生成的隨機層數(shù)來決定將當前節(jié)點存在幾層鏈表中。

為什么要這樣設計呢?

這樣設計的目的是為了保證 Redis 的執(zhí)行效率。

為什么要生成隨機層數(shù),而不是制定一個固定的規(guī)則,比如上層節(jié)點是下層跨越兩個節(jié)點的鏈表組成,如下圖所示:

如果制定了規(guī)則,那么就需要在添加或刪除時,為了滿足其規(guī)則,做額外的處理,比如添加了一個新節(jié)點,如下圖所示:

這樣就不滿足制定的上層節(jié)點跨越下層兩個節(jié)點的規(guī)則了,就需要額外的調整上層中的所有節(jié)點,這樣程序的效率就降低了,所以使用隨機層數(shù),不強制制定規(guī)則,這樣就不需要進行額外的操作,從而也就不會占用服務執(zhí)行的時間了。

添加流程

Redis 中跳躍表的添加流程如下圖所示:

  1. 第一個元素添加到最底層的有序鏈表中(最底層存儲了所有元素數(shù)據(jù))。
  2. 第二個元素生成的隨機層數(shù)是 2,所以再增加 1 層,并將此元素存儲在第 1 層和最低層。
  3. 第三個元素生成的隨機層數(shù)是 4,所以再增加 2 層,整個跳躍表變成了 4 層,將此元素保存到所有層中。
  4. 第四個元素生成的隨機層數(shù)是 1,所以把它按順序保存到最后一層中即可。

其他新增節(jié)點以此類推。

隨機層數(shù)源碼分析

隨機層數(shù)的源碼在 t_zset.c/zslRandomLevel(void) 中,如下所示:

int zslRandomLevel(void) {
    int level = 1;
    while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
        level += 1;
    return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

從源碼可知,隨機層數(shù)有 50% 的概率被分配到 Level 1,25% 的概率被分配到 Level 2,12.5% 的概率被分配到 Level 3,以此類推。

Redis 跳躍表默認允許最大的層數(shù)是 32,此值在 ZSKIPLIST_MAXLEVEL 源碼中被定義。

小結

跳躍表是由多個有序的鏈表組成的,最底層存儲了所有元素的數(shù)據(jù),這樣存儲讓它的查詢效率更高,查詢復雜度從 O(n) 變?yōu)榱?O(log n)。跳躍表的添加流程是根據(jù)節(jié)點生成的隨機層數(shù),將它插入到最底層節(jié)點和上層的 N-1 層節(jié)點中,描述添加流程的關鍵就是理解隨機層數(shù)以及其背后的原理。

參考 & 鳴謝

https://segmentfault.com/a/1190000022028505。

責任編輯:姜華 來源: Java中文社群
相關推薦

2021-02-22 08:19:49

js前端元素

2020-11-10 09:17:03

Redis

2020-07-07 07:34:29

RedisSDS數(shù)據(jù)結構

2023-02-08 07:52:36

跳躍表數(shù)據(jù)結構

2021-07-22 09:53:34

Vector類Java添加元素

2020-01-17 18:40:38

Python游戲代碼

2024-06-03 10:07:22

Vector類元素向量

2023-07-20 15:37:50

Bash數(shù)組

2010-09-16 15:56:15

SQL Server表

2009-12-07 15:02:48

PHP搜索數(shù)組

2021-08-03 10:24:59

數(shù)據(jù)跳躍鏈表結構

2021-03-12 08:19:20

數(shù)組跳躍游戲

2023-07-13 08:19:30

HaspMapRedis元素

2023-03-04 21:05:53

JAVA泛型通配符

2009-08-20 15:33:03

C#跳躍語句

2023-12-13 07:29:12

Redis元素Set

2021-04-23 09:41:50

元素邊框CSS

2010-10-13 10:03:08

MySQL修改表結構

2010-09-28 15:07:14

SQL語句

2021-12-08 09:11:41

前端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品一区二三区不卡 | 成人精品国产免费网站 | 成人一区二区三区 | 欧美性成人 | 欧美一区二区免费 | 日本爱爱视频 | 国产一区| 中文字幕在线一区 | 午夜免费在线电影 | 在线播放中文字幕 | 欧美一区二区视频 | 2019中文字幕视频 | 欧美精品久久久 | 欧美最猛黑人xxxⅹ 粉嫩一区二区三区四区公司1 | 男人的天堂在线视频 | 黑人巨大精品欧美黑白配亚洲 | 福利视频三区 | 欧美精品中文字幕久久二区 | www.日韩| 老司机久久 | 中文字幕日韩一区 | 夜操 | 伊人精品视频 | 国产精品国产三级国产aⅴ原创 | 婷婷综合久久 | 亚洲精品视频久久 | 国产黄色大片 | 国产一区二区三区视频在线观看 | www精品美女久久久tv | 成人深夜福利 | 国产成人高清成人av片在线看 | 日韩视频在线播放 | 天天玩天天干天天操 | 91久久国产精品 | 色婷婷久久久久swag精品 | 国产精品久久久久久一区二区三区 | 精品三级在线观看 | 久久久久久高潮国产精品视 | 日韩高清电影 | 国产精品成av人在线视午夜片 | 粉嫩av久久一区二区三区 |