国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

帶你徹底擊潰跳表原理及其Golang實現(xiàn)!(內(nèi)含圖解)

共 8046字,需瀏覽 17分鐘

 ·

2022-01-09 08:05


導(dǎo)語?|?最近在看《Redis設(shè)計與實現(xiàn)》這本書,書中簡單描述了跳表的性質(zhì)和數(shù)據(jù)結(jié)構(gòu),但對它的具體實現(xiàn)沒有詳細描述。本文是基于我個人對跳表原理的深入探究,并通過golang實現(xiàn)了一個基礎(chǔ)跳表的理解和實踐。


前言


書里對跳表結(jié)構(gòu)的描述是這樣的:



跳躍表節(jié)點:


 typedef struct zskiplistNode{     // 后退指針     struct zskiplistNode *backward;     // 分值     double score;     // 成員對象     robj *obj;     // 層     struct zskiplistLevel{         // 前進指針         struct zskiplistNode *forward;         // 跨度         unsigned int span;    } level[]; } zskiplistNode;


跳躍表結(jié)構(gòu):


typedef struct zskiplist{     // 表頭節(jié)點和表尾節(jié)點     struct zskiplistNode *header, *tail;     // 表中節(jié)點數(shù)量     unsigned long length;     // 表中層數(shù)最大的節(jié)點的層數(shù)     int level; } zskiplist;


雖然大概懂了跳表是一種怎么樣的存在,它有媲美平衡樹的效率,但比平衡樹更加容易實現(xiàn),但這本書并沒有詳細描述跳表的實現(xiàn),其中一些關(guān)鍵點也沒有說明,比如:


為什么表頭節(jié)點是不被計算在length屬性里?新增節(jié)點時是如何決定level的指針指向哪個后繼節(jié)點?為什么zset分值可以相同而成員對象不能相同?


為了解答這些問題,我決定完全弄懂跳表的原理,自己實現(xiàn)一個基礎(chǔ)的跳表。



一、跳表的原理


(一)有序單鏈表和二分查找法


顧名思義,有序單鏈表就是節(jié)點的排列是有順序的鏈表。



如果我們想從中找到一個節(jié)點,比如15,除了從頭節(jié)點開始遍歷,是否有其他方式?


經(jīng)典的查找算法中,有專門針對一個有序的數(shù)據(jù)集合的算法,即“二分算法”,以O(shè)(logN)的時間復(fù)雜度進行查找。它通過對比目標(biāo)數(shù)據(jù)和中間數(shù)據(jù)的大小,在每輪查找中直接淘汰一半的數(shù)據(jù):


  • 中間節(jié)點數(shù)字為10(10或8都可以作為中間節(jié)點),比目標(biāo)15小,所以排除10之前的4個數(shù)據(jù),在10-21中查找。


  • 中間節(jié)點為18 ,比目標(biāo)15大,排除18及之后的2條數(shù)據(jù),在10-15中查找。


  • 中間節(jié)點為15 ,與目標(biāo)一致,查找結(jié)束。


設(shè)想在鏈表中,我們參考二分算法的思想,為“中間節(jié)點”加索引,就能像二分算法一樣進行鏈表數(shù)據(jù)的查找了。



OK,現(xiàn)在我們將每一個中間節(jié)點抽了出來,組成了另一條鏈表,即一級索引,一級索引的每個節(jié)點都指向原單鏈表對應(yīng)的節(jié)點,這樣可以通過二分算法來快速查找有序單鏈表中的節(jié)點了。


如果原鏈表節(jié)點數(shù)量太多將會導(dǎo)致一級索引的節(jié)點數(shù)量也很多,這時需要繼續(xù)向上建立索引,選取一級索引的中間節(jié)點建立二級索引。



這就是跳表的本質(zhì)是對有序鏈表的改造,為單鏈表加多層索引,以空間換時間的策略,解決了單鏈表中查詢速度的問題,同時也能快速實現(xiàn)范圍查詢


鏈表節(jié)點數(shù)少時提升的效果有限,但當(dāng)鏈表長度達到1000甚至10000時,從中查找一個數(shù)的效率會得到極大的提升。



(二)跳表索引的更新


  • 二叉樹和跳表的退化


前言中提到,跳表具有媲美平衡樹的效率,平衡樹之所以稱之為平衡樹,是為了解決普通樹結(jié)構(gòu)在極端情況下容易退化成一個單鏈表的問題,每次插入或刪除節(jié)點時,會維持樹的平衡性。


下面這種二叉樹具有O(log n) 的查找時間復(fù)雜度,但在極端情況下容易發(fā)生退化,比如刪除了4,5,6三個節(jié)點后,會退化為單鏈表,查詢時間復(fù)雜度退化為O(n).



退化后的二叉樹:



如果跳表在插入新節(jié)點后索引就不再更新,在極端情況下,它可能發(fā)生退化,比如下面這種情況:



10到100之間插入n多個節(jié)點,查詢這其中的數(shù)據(jù)時,查詢時間復(fù)雜度將退化到接近O(n)。既然跳表被稱之為媲美平衡樹的數(shù)據(jù)結(jié)構(gòu),也必然會維護索引以保證不退化。


  • 跳表索引的維護


通過晉升機制。既然現(xiàn)在跳表每兩個原始鏈表節(jié)點中有一個被建立了一級索引,而每兩個一級索引中有一個被建立了二級索引,n個節(jié)點中有n/2個索引,可以理解為:在同一級中,每個節(jié)點晉升到上一級索引的概率為1/2。


如果不嚴格按照“每兩個節(jié)點中有一個晉升”,而是“每個節(jié)點有1/2的概率晉升”,當(dāng)節(jié)點數(shù)量少時,可能會有部分索引聚集,但當(dāng)節(jié)點數(shù)量足夠大時,建立的索引也就足夠分散,就越接近“嚴格的每兩個節(jié)點中有一個晉升”的效果。


當(dāng)然,晉升的概率可以根據(jù)需求進行調(diào)整,1/3或1/4,晉升概率稍小時,空間復(fù)雜度小,但查詢效率會降低。在下文中,我們將晉升率設(shè)置為p。



(三)時間復(fù)雜度與空間復(fù)雜度


  • 時間復(fù)雜度


結(jié)論:跳表的時間復(fù)雜度為O(log n)


證明:


按二分法進化出的跳表,無論是原鏈表還是N索引,都是每兩個節(jié)點中有一個被用作上一級索引。這個過程我們稱之為“晉升”,晉升的概率為p。


假設(shè)原鏈表節(jié)點數(shù)量為n,一級索引節(jié)點數(shù)為n*p^1,二級索引節(jié)點數(shù)為n*p^2,以此類推,h級索引的節(jié)點數(shù)應(yīng)為n*(p^h)。


最高層的期望節(jié)點數(shù)應(yīng)為1/p,我的理解是:小于等于這個期望數(shù),再高一層索引的期望節(jié)點數(shù)將為1,沒有意義了。


根據(jù)上述推算,易得一個跳表的期望索引高度h為:



加上底層的原始鏈表,跳表的期望總高度H為:



查找索引時,我們運用倒推的思維,從原始鏈表上的目標(biāo)節(jié)點推到頂層索引的起始節(jié)點,示意圖如下:



當(dāng)我們在底層節(jié)點時,只有兩種路徑可走,向上或向左,向上的概率為p,向左的概率為1-p。


假設(shè)C(i)為一個無限長度的跳表中向上爬i層的期望代價(即經(jīng)過的節(jié)點數(shù)量)


爬到第0層時,無需經(jīng)過任何節(jié)點,所以有:



爬到第1層時,可能有兩種情況:


從有p的概率是從第0層直接爬升1個節(jié)點,這種情況經(jīng)過的節(jié)點數(shù)為:



有1-p的概率是從第1層向左移動一個節(jié)點,則經(jīng)過的節(jié)點數(shù)為:



則有:



解得:C(i) = i/p


當(dāng)爬到期望中的最高層——第h層時,則期望步數(shù)為h/p,在第h層,繼續(xù)向左走的期望步數(shù)不會超過當(dāng)前層節(jié)點的期望總和1/p,向上走的期望步數(shù)也不會超過當(dāng)前層節(jié)點的期望總和1/p,全部加起來,從最底層的目標(biāo)節(jié)點到最頂層的頭節(jié)點,期望步數(shù)為h/p+2/p,將上面h的公式帶入,忽略常量,時間復(fù)雜度為O(log n)。


  • 空間復(fù)雜度


空間復(fù)雜度基本上就是等比數(shù)列之和的計算,比值為p。


直接說結(jié)果為O(n)



二、跳表的實現(xiàn)


為了更好地理解跳表,自己參考著跳表的原理,嘗試手擼一條跳表,當(dāng)然這是最基礎(chǔ)的,沒有redis跳表那樣豐富的能力,粗略實現(xiàn)了對數(shù)字的增刪改查,以插入的數(shù)字作為排序的基準(zhǔn),不支持重復(fù)數(shù)字的插入。


redis跳表在經(jīng)典跳表之上有額外的實現(xiàn):


  • 經(jīng)典跳表不支持重復(fù)值,redis跳表支持重復(fù)的分值score。


  • redis跳表的排序是根據(jù)score和成員對象兩者共同決定的。


  • redis跳表的原鏈表是個雙向鏈表。


在這之前需要說明,索引的節(jié)點其實并不是像底層鏈表一樣的節(jié)點Node,而是一種Level層結(jié)構(gòu),每個層中都包含了Node的指針,指向下一個節(jié)點。


(一)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)


const MaxLevel = 32const p = 0.5
type Node struct { value uint32 levels []*Level // 索引節(jié)點,index=0是基礎(chǔ)鏈表}
type Level struct { next *Node}
type SkipList struct { header *Node // 表頭節(jié)點 length uint32 // 原始鏈表的長度,表頭節(jié)點不計入 height uint32 // 最高的節(jié)點的層數(shù)}
func NewSkipList() *SkipList { return &SkipList{ header: NewNode(MaxLevel, 0), length: 0, height: 1, }}
func NewNode(level, value uint32) *Node { node := new(Node) node.value = value node.levels = make([]*Level, level)
for i := 0; i < len(node.levels); i++ { node.levels[i] = new(Level) } return node}


這里的p就是上面提到的節(jié)點晉升概率,MaxLevel為跳表最高的層數(shù),這兩個數(shù)字可以根據(jù)需求設(shè)定,根據(jù)上面推出的跳表高度公式:



可以倒推出此跳表的容納元素數(shù)量上限,n為2^32個。



(二)插入元素


重點在于如何確認插入的這個新節(jié)點需要幾層索引?通過下面這個函數(shù)根據(jù)晉升概率隨機生成這個新節(jié)點的層數(shù)。


func (sl *SkipList) randomLevel() int {  level := 1  r := rand.New(rand.NewSource(time.Now().UnixNano()))  for r.Float64() < p && level < MaxLevel {    level++  }  return level}


可以看出,默認層數(shù)為1,即無索引,通過隨機一個0-1的數(shù),如果小于晉升概率p,且總層數(shù)不大于最大層數(shù)時,將level+1。


這樣就有:


  • 1/2的概率level為1


  • 1/4的概率level為2


  • 1/8的概率level為3


  • ......


這里需要注意一下,上面我們說有1/2的概率有一層索引,即level為2的概率應(yīng)該是1/2,為什么這里是1/4呢?而位于第一層的原始鏈表存在的概率應(yīng)該是1,這里為什么level=1的概率為1/2呢?


原因在于,當(dāng)level為2時,同時也表示存在第一層;當(dāng)level為3時,同時也存在第一層和第二層;畢竟不能出現(xiàn)“空中閣樓”。所以:


  • 新節(jié)點存在原鏈表節(jié)點的概率為1/2+1/4+1/8+...=1


  • 新節(jié)點存在一層索引的概率為1/4+1/8+1/16+...=1/2


  • 新節(jié)點存在二層索引的概率為1/8+1/16+1/32+...=1/4


插入元素的具體代碼如下:


func (sl *SkipList) Add(value uint32) bool {  if value <= 0 {    return false  }  update := make([]*Node, MaxLevel)  // 每一次循環(huán)都是一次尋找有序單鏈表的插入過程  tmp := sl.header  for i := int(sl.height) - 1; i >= 0; i-- {        // 每次循環(huán)不重置 tmp,直接從上一層確認的節(jié)點開始向下一層查找    for tmp.levels[i].next != nil && tmp.levels[i].next.value < value {      tmp = tmp.levels[i].next    }
// 避免插入相同的元素 if tmp.levels[i].next != nil && tmp.levels[i].next.value == value { return false }
update[i] = tmp }
level := sl.randomLevel() node := NewNode(uint32(level), value) // fmt.Printf("level:%v,value:%v\n", level, value)
if uint32(level) > sl.height { sl.height = uint32(level) }
for i := 0; i < level; i++ {
// 說明新節(jié)點層數(shù)超過了跳表當(dāng)前的最高層數(shù),此時將頭節(jié)點對應(yīng)層數(shù)的后繼節(jié)點設(shè)置為新節(jié)點 if update[i] == nil { sl.header.levels[i].next = node continue } // 普通的插入鏈表操作,修改新節(jié)點的后繼節(jié)點為前一個節(jié)點的后繼節(jié)點,修改前一個節(jié)點的后繼節(jié)點為新節(jié)點 node.levels[i].next = update[i].levels[i].next update[i].levels[i].next = node }
sl.length++ return true}


數(shù)組update保存了每一層對應(yīng)的插入位置。


  • 從頭節(jié)點的最高層開始查詢,每次循環(huán)都可以理解為一次尋找有序單鏈表插入位置的過程。


  • 找到在這層索引的插入位置,存入update數(shù)組中。


  • 遍歷完一層后,直接使用這一層查到的節(jié)點,即代碼中的tmp開始遍歷下一層索引。


  • 重復(fù)1-3步直到結(jié)束。


  • 獲取新節(jié)點的層數(shù),以確定從哪一層開始插入。如果層數(shù)大于跳表當(dāng)前的最高層數(shù),修改當(dāng)前最高層數(shù)。


  • 遍歷update數(shù)組,但只遍歷到新節(jié)點的最大層數(shù)。


  • 增加跳表長度,返回true表示新增成功。


比如下面這張?zhí)?,我要新增元?,最高高度為5,當(dāng)前最高高度為3:



update長度為5


那么會從3層開始向下遍歷,在二級索引這層找到9應(yīng)該插入的位置——1和10之間,update[2]記錄包含1的節(jié)點。


在一級索引這層找到9應(yīng)該插入的位置——7和10之間,update[1]記錄了包含7的節(jié)點。


在原鏈表這層找到9應(yīng)該插入的位置——8和10之間,update[0]記錄了包含8的節(jié)點。


假設(shè)新節(jié)點的level為4,則修改當(dāng)前最高高度為4,然后開始逐層插入這個新節(jié)點,update[3]為空,因為目前整個跳表的高度只有3,所以需要將三級索引上的節(jié)點9插入到頭節(jié)點后面,插入過程與普通的鏈表插入無異。示意圖如下:




(三)刪除元素


func (sl *SkipList) Delete(value uint32) bool {  var node *Node  last := make([]*Node, sl.height)  tmp := sl.header  for i := int(sl.height) - 1; i >= 0; i-- {
for tmp.levels[i].next != nil && tmp.levels[i].next.value < value { tmp = tmp.levels[i].next }
last[i] = tmp // 拿到 value 對應(yīng)的 node if tmp.levels[i].next!=nil&&tmp.levels[i].next.value == value { node = tmp.levels[i].next } }
// 沒有找到 value 對應(yīng)的 node if node == nil { return false }
// 找到所有前置節(jié)點后需要刪除node for i := 0; i < len(node.levels); i++ { last[i].levels[i].next = node.levels[i].next node.levels[i].next = nil }
// 重定向跳表高度 for i := 0; i < len(sl.header.levels); i++ { if sl.header.levels[i].next == nil { sl.height = uint32(i) break } }
sl.length--
return true}


與插入節(jié)點思路一致,從最上層開始向下遍歷尋找,找到需要刪除的節(jié)點的前置節(jié)點并記錄在 last 數(shù)組中,然后修改前置節(jié)點指針的指向。



(四)查找


解決了增刪,剩下的查詢就很簡單了,可以查找對應(yīng)value的node,也可以查找一個范圍。


查找范圍即先找到范圍前邊界的節(jié)點,再通過鏈表向后遍歷即可。


這里我只實現(xiàn)了查找單個node的函數(shù):


func (sl *SkipList) Find(value uint32) *Node {  var node *Node  tmp := sl.header  for i := int(sl.height) - 1; i >= 0; i-- {    for tmp.levels[i].next != nil && tmp.levels[i].next.value <= value {      tmp = tmp.levels[i].next    }    if tmp.value == value {      node = tmp      break    }  }  return node}



三、redis的跳表實現(xiàn)


上述是一個標(biāo)準(zhǔn)跳表的原理和實現(xiàn),redis中的跳表還有所不同,它提供了更多的特性和能力:


  • 經(jīng)典跳表不支持重復(fù)值,redis跳表支持重復(fù)的分值score。


  • redis跳表的排序是根據(jù)score和成員對象兩者共同決定的。


  • redis跳表的原鏈表是個雙向鏈表。


redis中,跳表只在zset結(jié)構(gòu)有使用。zset結(jié)構(gòu)在成員較少時使用壓縮列表 ziplist作為存儲結(jié)構(gòu),成員達到一定數(shù)量后會改用map+skiplist作為存儲結(jié)構(gòu)。這里只討論使用skiplist的實現(xiàn)。


zset結(jié)構(gòu)要求,分值可以相同,但保存的成員對象不能相同。zset對跳表排序的依據(jù)是“分值和成員對象”兩個維度,分值可以相同,但成員對象不能一樣。分值相同時,按成員對象首字母在字典的順序確定先后。


zset還維護了一個map,保存成員對象與分值的映射關(guān)系,被用來通過成員對象快速查找分值,定位對應(yīng)的節(jié)點,在ZRANK、ZREVRANK、ZSCORE等命令中均有使用。


另外,這個map還用于插入節(jié)點時,判斷是否存在重復(fù)的成員對象。見下面redis源碼中的dictFind函數(shù)。


int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, double *newscore) {    // ...    /* Update the sorted set according to its encoding. */    if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {        // ...    } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {        zset *zs = zobj->ptr;        zskiplistNode *znode;        dictEntry *de;
de = dictFind(zs->dict,ele); if (de != NULL) { // 已經(jīng)存在 // ... } else if (!xx) { // 不存在,插入 ele = sdsdup(ele); znode = zslInsert(zs->zsl,score,ele); serverAssert(dictAdd(zs->dict,ele,&znode->score) == DICT_OK); *out_flags |= ZADD_OUT_ADDED; if (newscore) *newscore = score; return 1; } else { *out_flags |= ZADD_OUT_NOP; return 1; } }}



四、回顧問題


前面提到,在看《Redis設(shè)計與實現(xiàn)》這本書時我有幾點疑問,在詳細了解跳表之后現(xiàn)在就完全理解了。


(一)為什么表頭節(jié)點是不被計算在length屬性里?


因為表頭節(jié)點是初始化跳表時提供的空節(jié)點,不保存任何節(jié)點,只用于提供各級索引的入口。



(二)新增節(jié)點時是如何決定level的指針指向哪個后繼節(jié)點?


通過分值和成員對象共同決定,判斷新節(jié)點的插入位置和順序。分值相同時,按成員對象首字母在字典的順序確定先后。


經(jīng)典跳表也同樣需要一個維度來確定插入的順序,我的跳表實現(xiàn)中直接使用了新節(jié)點的值作為排序的維度。



(三)為什么zset分值可以相同而成員對象不能相同?


根據(jù)第二個問題的答案,如果都相同,就無法確定插入的位置和順序。



?作者簡介


馮啟源

騰訊后臺開發(fā)工程師

騰訊后臺開發(fā)工程師,畢業(yè)于中南大學(xué),目前負責(zé)騰訊教育業(yè)務(wù)的后端開發(fā)工作,希望能用技術(shù)改善人們的生活。



?推薦閱讀


被引入C++標(biāo)準(zhǔn)庫!為什么說智能指針是解決問題的“神器”?

Elasticsearch 可搜索快照技術(shù)原理及最佳實踐

手把手帶你從0搭建一個Golang ORM框架(全)!

淺談Golang兩種線程安全的map




瀏覽 71
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 香蕉视频免费| 亚洲欧美成人在线视频| 国产在线毛片| 91探花国产综合在线精品| 91午夜福利| 国产人成视频免费观看| www日本在线| 一本色道久久综合无码人妻软件 | 综合网操笔| 成人V| 成人三级电影在线观看| 97福利视频| 免费福利在线视频| 日韩欧美国产综合| 天天色天天爱| 国产操b| 一级a片在线免费观看| 99精品自拍| 日韩精品三级| av女人天堂| 奶大丰满一乱一视频一区二区三区在 | 狼友精品| 97精品视频| 人人妻人人澡人人DⅤD| 手机看片1024国产| 少妇特黄A一区二区三区| 久久毛片人妻| 国产精品久久久久久久久久久久久久久久 | 91麻豆精品国产91久久久久久久久| 十八禁福利网站| 精品三级在线观看| 亚洲成人娱乐网| 欧美一级爱爱| 91嫩草久久久久久久| 国产视频一二三| 国产无码激情| 国产国产国产在线无码视频| 亚洲国产成人一区二区| 怡春院成人| 激情久久五月天| 日韩一区二区三区精品| 欧美日韩精品久久久免费观看| 欧美footjob| eeuss久久| 操逼网站在线观看| 国产操女人| 国产乱伦AV网站| 91精品人妻一区二| 特一级黄色电影| 国产又大又粗又黄| 国产少妇| 国产字幕在线观看| 深爱五月激情| 中文字幕免费在线看一区七区| 亚洲成人精品AV| 黄色三级毛片| 天天射夜夜骑| 少妇bbb搡bbbb搡bbbb| 九九偷拍视频| 日韩日逼网站| 亚洲综合天堂| 激情五月天小说网| 午夜AV在线免费观看| 亚洲高清无码在线| 成人欧美一区二区三区在线观看 | 西西人体WW大胆无码| 91成人免费在线观看| 黄色av免费观看| 江苏妇搡BBBB搡BBBB小说 | 成人在线视频观看| 你懂得视频| 蜜桃秘av一区二区三区安全| 2019狠狠操| 91丝袜一区二区三区| 99在线精品视频| 中文观看| 爱爱视频免费看| 韩日综合在线| 天天干一干| 人妻中文无码| 免费一区视频| 黄片AAA| 内射网站在线观看| 天天操天天干天天射| 久久久综合网| 三根一起进菊眼| 色欲成人AV| 成人电影一区二区| 日韩高清久久| 北条麻妃99精品| 色婷婷久久久久swag精品| 免费视频无码| 中文字幕1| 狼人综合在线| 黑人AV| 国产麻豆精品成人免费视频| 五月丁香在线视频| 国产精品毛片视频| 国产精品123| 大香蕉9999| 天天综合视频| 内射老太太| 91麻豆免费视频网站| 人人超碰人人| 无码迷穴| 91狠狠综| 国产精品成人3p一区二区三区 | 伊人9| 51午夜| 久久亚洲AV无码午夜麻豆| 精品乱伦视频| 免费毛片基地| 亚洲AV无码成人精品区www | 好吊顶亚洲AV大香蕉色色| 欧美天天| 香蕉操逼| 亚洲性爱网站| 亚洲系列中文字幕| 专业操美女视频网站| 国产黄色视频网站在线观看| 国产男女性爱视频播放| 欧美狠狠撸| 99re6热在线精品视频功能| 天天草天天干| 国产三级片视频在线观看| 久一精品| 国产麻豆免费| 日韩黄色一级视频| 久草视频在线免费看| 国产精品婷婷| 久久6精品| 欧美色伊人| 一级内射视频| 一本色道久久88亚洲精品综合| 在线h片| 国产AV二区| 国产娇小13videos糟蹋 | h网站在线看| 欧美日韩有码视频网址大全| 国产精品porn| 黄色免费在线观看网站| 农村一级婬片A片AAA毛片古装| 人妻精品一区二区在线| 黄片一区二区三区| 一级一级a免一级a做免费线看内裤| 欧美成人三区性价比| 青青无码视频| 俺去日| 一区视频免费观看| 爱操AV| 一级日逼视频| 亚洲黄色电影| 亚州操逼片| 欧美亚洲国产精品| 人妻av在线| 91在线永久| 第一页在线| 韩国精品无码| 久久久久女人精品毛片九一| 黄色大片AV在线| www.日韩欧美| 人人人人人人人人操| 中文字幕日本电影| 免费看黄色视频| 国产精品无码中文在线| 亚洲无码手机在线| 婷婷五月天社区| 黄色无遮挡| 亚洲成人视频一区二区| 日韩三级电影| 国产色哟哟| 51精品日本| 国产人妻人伦精品一区| 色啪视频| 久久久久无码精品国产91福利| 久久久久久久久黄色| 日欧美美女逼| 超碰p| 免费Av网站| 在线不卡中文字幕| 日韩无码第一页| 黄色小网站在线观看| 日本一本草久p| 天天干少妇| 国产成人免费视频| 玖玖国产| 性生活黄色视频| 日本中文字幕在线观看视频 | 国精品无码一区二区三区在线秋菊 | AV大香蕉| 北条麻妃二区| 亚洲色图欧美另类| 性爱免费视频网站| 五月色婷婷综合| 日韩无码一区二区三区| 91人妻人人操人人爽| 91AV免费观看| 成人免费乱码大片a毛片蜜芽| 西西西444www无码视频| 日韩福利| 东方av在线观看| 91麻豆精品国产91久久久吃药| 自拍偷拍激情视频| 九九惹伊人| caobi999| 中文字幕日韩人妻| 亚洲日韩Av无码中文字幕美国 | 一道本视频在线免费观看| 亚洲在线大香蕉| 国产一级黄色大片| 日本在线www| 日韩中文字幕在线| 亚洲a视频| 国产无码区| 午夜福利成人网站| 亚洲XXXXX| 懂色AV无码中字幕一区| 少妇搡BBBB搡BBB搡毛片| 日韩精品欧美一区二区三区| 中文字幕第八页| 爱搞搞就要搞搞| 内射免费网站| 操美女大逼| 天堂8在线视频| 国精品无码一区二区三区在线| 国产亚洲视频在线观看视频| 99视频网站| 青青草青娱乐| 日韩成人一区二区三区| 91在线无精精品秘白丝| 日本一区二区三区免费观看| 国产成人精品一区| 天天日天天色天天干| 久久久久99精品成人片直播| 熟妇高潮一区二区高潮| 国产人与禽zoz0性伦| 姐弟乱伦性爱| 中文字幕精品人妻在线| 野花av| 99热18| 丰满岳乱妇一区二区三区全文阅读| 婷婷看片| 一级片黄片| 久久五月亭亭| 欧美影院亚洲| 中文字幕免费毛片| 亚洲操逼AV| 91无码高清视频| 日本欧美一级片| 日韩和的一区二区| 天天撸免费视频| 日韩操逼一区| 色第一页| 苍井空无码一区二区三区| 日本精品乱伦| 成人夜间视频| 操美女影院| 88AV视频| 免费无码A片在线观看全| 2026无码视频| 亚洲AV无码乱码AV| 91狠狠爱| 欧美亚洲系列| 亚洲欧美婷婷五月色综合| 亚洲精品在| 国产精品无码激情视频| 翔田千里在线一区二区三区| 欧美A级黄片| 成人免费视频一区| 欧一美一婬一伦一区二区三区| 亚洲免费视频在线看| 国产福利在线导航| 精品热99| 精东av| 97人人人人人人| 一本色道久久综合无码| 伊人看片| 亚洲制服在线观看| 视色网| 日韩欧美在线免费观看| 欧美性爱综合网| 日本Sm/调教/捆绑/紧缚| 日本少妇视频| 囯产精品久久久久久久久久久久久久 | 黄片免费看视频| 爱搞搞视频| 人人摸人人操人人| 亚洲激情网站| 五月婷婷丁香| 国产日本在线视频| 91久久久久久久久久久| 欧美黄网站在线观看| 天堂性爱AV| 777色色色| 大荫蒂视频另类XX| 日韩中文字码无砖| 国产主播福利| 98色色| 女生自慰网站在线观看| 中文字幕有码视频| 久草人妻| 操碰在线视频| 午夜操日在线| www.国产豆花精品区| 香蕉漫画在线观看18| 人妻少妇被猛烈进入中文字幕| 久久久久久久久久免费视频| 日韩激情视频在线观看| 日韩无码A| 91视频高清无码| 久色视频在线| 韩国中文无码| 嗯啊av| 97超碰碰| 国产欧美日韩成人| 97精品超碰一区二区三区| 国产成人无码精品一区秘二区 | 2018天天操天天干| 亚洲综合一区二区三区| 秋霞福利影院| 蜜臀99久久精品久久久懂爱| 91热在线| 91香蕉国产| 精品视频一区二区三区| 正在播放吴梦梦淫行| av在线影院| 一大高清日韩| 少妇人妻AV| 成人性爱在线播放| www.91在线| 日韩在观看线| 老女人操逼视频| 亚洲性爱片| 猛男大粗猛爽h男人味| 一道本无码在线视频| 青草精品视频| 后入少妇视频| 黄色操B视频| 久热福利| 亚洲秘无码一区二区三区观看| 欧美精产国品一| 日韩欧美小电影| 日韩一区在线视频| 69久久| 色片网| 久久理论| 日韩A片无码ⅩXXXX| 亚洲国产精品久久久久婷婷老年| 免费黄色一级视频| 欧美精产国品一二三区别| 欧美亚洲激情| 九七色色电影| 1插菊花网| 日韩成人高清无码| 在线免费看AV片| 啊啊啊啊啊靠逼| 亚洲乱伦视频| aa人人操夜夜操人人| 午夜ww| 青青伊人久久| 女神思瑞精品一区二区三区| 日日操人人操| 成人网站一区| 国产精品久久久无码专区| 青娱乐网站| 久久久久91| 婷婷成人小说| 黄色片国产| 国产精品久久久久久久久久王安宇 | 日韩有码第一页| 国产一级特黄aaa大片| 久久熟妇| 大香蕉91| 在线观看亚洲无码视频| 欧美成人视屏| 一欧美日韩免费/看| 嫩BBB槡BBBB槡BBBB免费视频| 国产在线中文字幕| 日韩无码黄色片| 一区二区三区四区五区无码| 九九热精品视频| 大肉大捧一进一出免费阅读| 人人澡人人爽人人精品| 91蜜桃传媒| 国产理论片在线观看| 国产又黄又爽| 国产91无码精品秘入口| 蜜桃传媒一区二区亚洲| 久久久www成人免费毛片| 欧美VA视频| 一纹A片免费观看| 欧美人成人无码| 久久久久久亚洲Av无码精品专口| 九九成人免费视频| 3344gc在线观看入口| 91人妻无码视频| 国产夫妻自拍AV| 一本大道香蕉av久久精东影业| 国产成人精品免费看视频| 天天干天天射天天操| 你懂的在线免费观看| 青青草精品视频| 五月天福利网| 黄色激情视频网站| 亚洲AV中文在线| 亚洲AV成人无码精品直播在线 | 91色欲| 三级成人免费| 日本一区二区三区免费视频| 中文字幕人妻丝袜二区电影| 动漫3d啪啪成人h动漫| 国产一级性爱| 国产av天堂| 亚洲三级在线免费观看| 亚洲一卡二卡| 免费视频亚洲| 国产成人精品一区二区| 操B影院| 五月婷婷在线观看| 五月黄色电影| 最新中文字幕| 91无码秘蜜桃一区二区三区-百度| 肉片无遮挡一区二区三区免费观看视频 | 69人妻人人澡人人爽久久| 西西4444WWW无码视频| 亚洲日韩免费| 尻屄视频| 黄片无码免费| 日韩99热| 一级特黄AAAA片| 操b视频免费| 亚洲免费专区| 韩国成人精品三级| 欧美日日| 午夜福利1000| 成人无码高清在线观看| 欧美日韩中文字幕| 东北奇淫老老妇| 波多野结衣无码视频在线观看| 国产丰满| a色视频| 日韩AV中文字幕在线| 中文字幕无码综合| 午夜成人精品视频| 少妇高潮在线| 黑人干亚洲人| 中文国产字幕| 亚洲三级在线免费观看| 中文字幕巨乱亚洲高清A片28| 一二三四区视频| 先锋影音男人| 婷婷伊人綜合中文字幕| 91丨PORN丨国产| 亚洲口味重一级黄片| 国产一区二区三区在线视频| a亚洲a| 久久午夜夜伦鲁鲁一区二区| 成人无码观看| 日韩A区| 大香伊人久久| 色婷婷av在线| 91丨人妻丨国产| 日韩中文字幕电影| 亚洲自拍中文字幕| www.色欲av| 精品天堂| 欧美日韩在线视频免费观看| 日韩精品成人AV| 精品无码秘人妻一区二区三区| 亚洲无码AV在线观看| 久艹久| av中文字幕在线播放| 欧美中文在线观看| 亚洲真人无码| 99热加勒比| 中文字幕免费在线视频| 欧美A黄片| 欧美老妇BBBBBBBBB| 熟女人妻ThePorn| 黄色成人视频网站在线观看| 91丨九色丨东北熟女| 中文字幕在线中文| 一区二区三区三级片| 欧洲激情网| 日皮视频在线| 91乱了伦国产乱子伦| 亚洲一级二级| 亚洲欧美日韩电影| 国产一级自拍| AV一二区| 成人福利| 东京热黄色| 人人舔人人爱| 怡红影院美乳| 午夜神马福利| 日韩中文字幕精品| 色色在线观看| 国产A√| 小黄片在线看| 中文无码高清视频| 伊人网站视频在线| 亚洲福利视频在线| 五月天婷婷激情网| 久久青娱乐| 91少妇精品| 国模精品无码一区二区免费蜜桃| 在线视频一区二区三区四区| 不卡无码免费视频| 91大香蕉| 亚洲69视频| 四虎麻豆| 黄色草莓视频| 老妇性BBWBBWBBWBBW| 婷婷香蕉| 小h片| 996热re视频精品视频| 韩国色情中文字幕| 91在线超碰| 久久九九综合| 三区在线观看| 啊啊嗯嗯视频| 亚洲AV成人无码久久精品麻豆| 亚洲无线视频| 亚洲一| 国产精品成人3p一区二区三区| 亚洲在线免费| 午夜A区| 秋霞久久| 亚洲综合图色40p| 就去色色五月丁香婷婷久久久| 欧美成人无码A片免费| AV久草| 欧美视频区| 国产乱伦精品视频| 肏屄网站| 中文字幕精品在线观看| 黑人精品欧美一区二区蜜桃| 无码人妻精品一区二区蜜桃网站| 亚洲免费MV| 欧美a视频| 日韩av免费看| 91麻豆精品国产91久久久久久| 国产性受XXXXXYX性爽| 91夫妻交友视频| 黃色一级A片一級片| 在线观看污网站| 亚洲一卡二卡三卡四卡免| 中文字幕亚洲中文字幕| 国产黄色大片| 大香蕉人人| 亚洲AV无码| 国产免费无码视频| 在线观看欧美黄片| 91丨人妻丨国产| 国产777| 欧美一级免费| 91视频国产精品| 亚洲激情自拍| 免费欧美成人网站| 正在播放ADN156松下纱荣子| 午夜av在线| 无码精品人妻一区二区三区漫画| 精品美女视频在线观看免费软件| 伊人大香蕉视频在线观看| 免费AV资源在线观看| av干在线| 国产精品无码一区二区三区| 成人免费在线观看| 国产a片免费看| 麻豆精品国产传媒| 制服.丝袜.亚洲.中文.豆花| 北条麻妃无码一区三区| 91香蕉视频18| 久久久久无码精品亚洲日韩| 欧美肉大捧一进一出小说| 成年视频网站| 尻屄视频免费| 国产黄色一区| 美国操逼片| 日本二区| 国产免费小视频| 蜜芽成人在线| 成人午夜小视频| 精东av| 全国男人的天堂网站| 欧美啪啪视频| 中文字幕高清在线中文字幕中文字幕 | 中文字幕一区二区蜜桃| 肏屄网站| 久热无码| 国产福利电影在线观看| 国产精品视频免费在线观看| 亚洲字幕av| 国产一道本| 亚洲va欧美va| 这里视频很精彩免费观看电视剧最新 | 久久久女女女女999久久| 初学影院WWWBD英语完整版在线观看 | 日韩操b| 在线观看视频91| 91国语对白| 日日骚av一区二区三区| AV香蕉| 亚洲综合人妻| 无码三级午夜久久人妻| 免费看黄色电影| 日韩免费在线视频观看| 五月天综合网| 天天干天天添| H片在线免费观看| 免费亚洲无码| jjzz国产| 日韩三级片无码| 婷婷俺也去| 精品国内自产拍在线观看视频| 免费看黄色毛片| 黄色福利网| 欧美精品国产动漫| 色男天堂| 天天干天天撸影视| 人人舔视频| 一区二区av| 毛片二区| 首页-91n| 亚洲天堂精品在线观看| 国产福利视频导航| 国产黄片免费在线观看| 色婷婷成人| 色色A| 欧美在线色| 少妇搡BBBB搡BBB搡HD(| 中文字幕av久久爽爽| 国产香蕉视频在线播放| 中国毛片视频| 婷婷国产| 玖热精品| 91无码高清视频| 中文字幕亚洲中文字幕| 久草视频免费在线播放| 久久久久久成人无码| 精品少妇3p| 国产操穴视频| 一区二区在线不卡| av干在线| Av天堂图片在线| 丁香婷婷色五月激情综合三级三级片欧美日韩国 | A级成人网站| 北条麻妃91| 欧美性69| 毛片在线观看网站| 亚洲AV电影网| 黄色一级a片| 蜜桃AV一区二区三区| www亚洲无码| 久久久久99精品成人网站| 麻豆二区| 三级视频网| 性爱无码网站| 国产欧美精品一区二区色综合| 亚洲无码成人视频| 日韩黄色在线| 国产91探花秘入口| 岛国无码破解AV在线播放| ppypp电影频道| 99福利视频| 国产又大又粗| 婷婷五月丁香花| 亚洲无码一本道| 2025AV天堂| 国产成人无码区免费AV片在线 | 亚州无码一区| 国产婷婷色| 婷婷社区五月天| 69成人免费视频| 午夜成人AV| 九哥草逼网| 日本a级视频| 中文字幕一区二区三区四虎在线| 欧美群交在线| 成人做爰A片一区二区app| 俺来也俺也去| 中文字幕在线观看视频www| 成人无码一区| 黄色片免费| 日韩一级黄色电影| 欧美日逼视频| 三级片在线看片AV| 蜜桃av秘无码一区二区三| 亚洲日韩中文无码| 国产一区免费视频| 91AV久久| www.jiujiujiu| 免费看黄色片视频| 成人无码91| 久久公开视频| 日皮视频在线免费观看| 北条麻妃在线中文字幕| 99ri国产| 91含羞草www·Com| www.污| 日韩精品人妻中文字幕蜜乳| 亚洲国产精品视频| 中字无码| 777免费观看成人电影视频 | 伊人狼人香蕉| 农村新婚夜一级A片| 蜜桃视频网站在线观看| gogogo免费高清在线偷拍| 人人妻人人澡人人DⅤD| 人妻18无码人伦一区二区三区精品| 三级爱爱| 国产手机拍视频推荐2023| 日本成人毛片| 无套内射学生妹去看片| 张柏芝BBw搡BBBB槡BBBBHDfree | 人人色在线| 九九国产精品| 久久精品中文字幕| 伊人黄片| 蜜臀av一区二区三区| 按摩性高湖婬AAA片A片中国| 国产无码电影网| 免费播放黄色成人片| 又色又爽| 亚洲综合成人网| 国产在线拍偷自揄拍无码一区二区| 亚洲免费一区二区| 草逼网站| 成人激情视频| AAA片网站| 最新毛片网站〖网:.〗| 人人妻人人操人人干| 国产男人天堂| 青娱乐91视频| 六月丁香视频| 日韩欧美中文在线| 欧美天堂在线| 国产婷婷久久Av免费高清| 欧美亚洲综合在线观看| 免费看A片视频| 午夜免费网站| 日本在线黄色视频| 欧美疯狂做受XXXXX高潮 | 伊人影院在线视频| 日韩A片无码ⅩXXXX| 在线观看视频一区| 操逼AⅤ| 五月色婷婷综合| 日韩欧美在线一区| 国产精品theporn| 国产91精品探花一区二区| 久久99老妇伦国产熟女| 大香蕉伊人视频| www.国产豆花精品区| 国产一区在线播放| 江苏妇搡BBBB搡BBBB-百度| 日日操日日摸| 精品久久成人| 国产精品99久久久久的广告情况 | 一级操逼大片| 真人一级片| 国产免费无码视频| 性爱视频无码| 久久人妻中文字幕| 高清中字无码| 五香丁香天堂网| 婷婷五月天激情电影| 久久免费在线视频| 国产九色| 亚洲午夜AV久久乱码| 中文字幕午夜福利| 天堂成人av| 国内精品久久久久久久久久| 日韩婬乱片A片AAA真人视频| 婷婷丁香综合| 日韩性爱在线| 亚洲欧美日韩无码| 蜜桃免费| 久久色婷婷| 3344gc在线观看入口| 欧美操B视频| 午夜老司机福利| 91人妻人人澡人人爽人人DVD| AV黄色在线| 久久精品视频99| 加勒比久久综合| 性欧美成人播放77777| 东北奇淫老老妇| 超碰婷婷| 91精品国产偷窥一区二区| 中文字幕91| 免费一级黄色毛片| xxx一区二区| 亚洲女人视频| 国产久久久久久久| 高清一区二区| 亚洲欧美另类图片| 免费无码在线视频| 热99re69精品8在线播放| 1024在线视频| 11孩岁女精品A片BBB| 做a视频| AV网站在线免费观看| 亚洲天堂2015| 最近中文字幕高清2019中文字幕| 免费看片av| 人人超碰人人| 青青草原在线| 丁香六月婷婷久久综合| 日本少妇性爱视频| 欧美区亚洲区| 国精产品一二四区黑人| 17.3c一起起草| 蜜桃视频欧美| 国产字幕| 操逼视频观看| 在线无码免费| 狼友视频免费| 91在线永久| 国产精品热| 亚洲视频一区| 日韩无码乱码| 刘玥一区二区三区| 婷婷精品国产a久久综合| 操逼三级视频| 91精品国产综合久久久久久久| 亚洲激情在线观看| 51妺嘿嘿午夜福利| 不卡一二三区| 无码蜜桃吴梦梦| 成人欧美视频| 亚洲麻豆| 水果派红桃AV解说| 国产嫩苞又嫩又紧AV在线| 俺来俺去| 九九操比| 亚洲欧美v在线视频| 蜜桃AV在线播放| 亚洲天堂中文字幕| 色婷婷欧美| 久操视频免费在线观看| 亚洲无码系列| 国产乱码精品一区二区三区的特点 | www五月天| 日日干天天操| 国产综合亚洲精品一区二| 亚洲一卡二卡三卡四卡免| 在线AⅤ| 丹麦电影《下午》| 在线观看中文字幕网站| 亚洲一区二区在线视频| 秋霞福利视频| 国产无码a| 欧美日韩成人片| 日韩国产av| 69堂在线观看| 少妇搡BBBB搡BBB搡HD(| 在线视频一区二区三区| www日韩无码| 美日韩在线| 一级a一级a爱片免费视频| 欲撸视频| 四色影视| 欧美午夜视频| 欧美亚洲色色网视频| 伊人大香在线| 亚洲天堂2025| gay成人在线观看| 一边做一边说国语对白| 成人精品无码免费视频| 久艹| 台湾精品一区二区三区| 亚洲老鸭窝| 成人av黄色三级片在线观看| 欧美污视频在线观看| 最近中文字幕mv第三季歌词| 中文字幕免费在线看一区七区 | 日本无码一区二区三三| 欧美一级高清片免费一级a | 亚洲一级Av无码毛片久久精品| 美女少妇激情BBBB| 极品美鮑20p| 国产在线观看免费视频| 大香蕉电影网站| 久久久久久久无码| 国产91在线视频| 97免费在线观看视频| 97精品国产97久久久久久免费| 神马午夜精品95| 欧美亚洲国产一区二区三区| 亚洲精品娱乐| 翔田千里被躁120分钟| 97久久精品| 足交在线观看| 人妻北条麻妃在线| 精品日韩一区二区三区| 日韩人妻精品无码| 日韩中文字幕在线高清| 北条麻妃99| 九九九在线观看视频|