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

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

共 9022字,需瀏覽 19分鐘

 ·

2022-07-31 13:16

導(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ù)雜度進行查找。它通過對比目標數(shù)據(jù)和中間數(shù)據(jù)的大小,在每輪查找中直接淘汰一半的數(shù)據(jù):


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


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


  • 中間節(jié)點為15 ,與目標一致,查找結(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ù)少時提升的效果有限,但當鏈表長度達到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的概率晉升”,當節(jié)點數(shù)量少時,可能會有部分索引聚集,但當節(jié)點數(shù)量足夠大時,建立的索引也就足夠分散,就越接近“嚴格的每兩個節(jié)點中有一個晉升”的效果。


當然,晉升的概率可以根據(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為:



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



當我們在底層節(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


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


  • 空間復(fù)雜度


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


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



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


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


原因在于,當level為2時,同時也表示存在第一層;當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ù)超過了跳表當前的最高層數(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ù)大于跳表當前的最高層數(shù),修改當前最高層數(shù)。


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


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


比如下面這張?zhí)?,我要新增元?,最高高度為5,當前最高高度為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,則修改當前最高高度為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)


上述是一個標準跳表的原理和實現(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é),目前負責騰訊教育業(yè)務(wù)的后端開發(fā)工作,希望能用技術(shù)改善人們的生活。



推薦閱讀


福利

我為大家整理了一份從入門到進階的Go學(xué)習資料禮包,包含學(xué)習建議:入門看什么,進階看什么。關(guān)注公眾號 「polarisxu」,回復(fù) ebook 獲?。贿€可以回復(fù)「進群」,和數(shù)萬 Gopher 交流學(xué)習。

瀏覽 45
點贊
評論
收藏
分享

手機掃一掃分享

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

手機掃一掃分享

分享
舉報

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

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 久久电影无码| 五月丁香婷婷啪啪| 亚洲视频三区| 亚洲美女喷水视频| 69无码| 97色在线| 亚洲成人第一页| 亚洲无码色色| 国产理论在线| 丁香花免费高清视频小说完整| 健身房被教练3p喷水了| 另类老妇性BBwBBw| 丰滿老婦BBwBBwBBw| 欧美色色色色色色| 国产精品主播| 国产视频第一页| 99爱免费视频| 99爱在线| 欧美一级操逼视频| 牛牛精品一区二区AV| 午夜操日在线| av高清无码| 天天色av| 麻豆视频一区二区| 国产无码播放| 超碰福利在线| 亚洲丁香网| 国产精品扒开腿做爽爽爽视频 | 国产麻豆精品成人免费视频| 亚洲一区二区免费视频| 青青操色| 日韩精品成人在线视频| 九九九热精品| 亚洲无码久久飞鱼网站| 欧美五月在线网址| 欧美一级片| 五月丁香网站| 少妇搡BBBB搡BBB搡澳门| 97人人爱| 婷婷久月| 好色婷婷| 亚洲无码视频一区二区| 久久午夜电影| 亚洲成人在线无码| 麻豆熟女| 高清无码不卡在线观看| 丰满熟妇人妻无码视频| 午夜在线无码| 少妇高潮一区二区三区99| 日韩无码人妻视频| 亚日韩在线| 高清av免费| 青青草五月天色婷婷丁香| 91成人做爰A片| 中文字幕无码av| 69成人网站| 日逼大片| 最好看的MV中文字幕国语| 五月婷久久| 久久4| 亚洲视频免费在线播放| 久久污| av在线免费观看网址| 国产成人无码精品| 日韩网站在线观看| 婷婷高清无码| 国产精品丝袜| 国产综合区| 日本黄色色情视频| 欧美三级无码| 日本视频免费| 日本在线无码| 大伊香蕉久久| 无码av免费| 天天操天天日天天操| 男人插女人网站| 久久精彩免费视频| 美日韩一区| 亚洲婷婷AV| 国产欧美日韩综合在线视频| 国产无码操逼视频| 大香蕉伊人视频在线观看| 亚洲一区亚洲二区| 成人精品一区二区无码| 亚洲天堂无| 成年人视频免费| 人人摸人人看人人草| 国产麻豆传媒| 好男人WWW社区在线视频夜恋| av无码毛片| www.99在线| 色播av| 人人操人人模| 免费网站观看www在线观| 激情无码一区二区三区| 亚洲无码免费播放| 41ts午夜福利| 97精品人妻一区二区三区在线| 久草视频大香蕉| 京熱大亂交无碼大亂交| 四lll少妇BBBB槡BBBB| 国产精品一区二区性色AV| 欧美激情亚洲| 国产精品无码永久免费不卡 | 一本道高清| 粉粉嫩嫩的18虎白女| 三级AV在线| 黄色免费在线观看视频| 18XXX亚洲HD护士JD| 国产黄色免费| 狼友视频一国产| 精品一区二区三区蜜桃臀www| 91麻豆国产在线观看| 久久亚洲中文| 日韩黄色电影在线| 一区二区av在线| 91成人视频免费观看| 操熟女视频| 欧美一级A片在线观看| 9l视频自拍蝌蚪9l成人| 欧美日韩国产成人在线| 岛国片资源| 五月婷婷丁香综合| 熟女人妻人蜜桃视频| 在线观看黄色视频网站| 一区在线视频| 亚洲高清无码久久| 人人澡人人爽欧一区| 97色碰| 屁屁影院CCYYCOM发布地 | 99ri国产| 欧美色色色色色色| 國產精品77777777777| 91豆花视频18| 东京热综合影院| 444444免费高清在线观看电视剧的注意| 水蜜桃成人在线| 91伊人久热精品| 国产黄片一区二区三区| 极品av| h国产在线| 色色影院| 777777视频| 中文人妻| 欧美熟妇性爱视频| 免费观看黄片网站| 国内精品久久久久久久久98| 亚洲美女在线观看| 淫淫五月天| 国产亚洲视频在线观看| 三级成人网站| av三级片在线播放| 亚洲福利社| 欧美内射在线| 蜜桃91精品入口| 日韩在线成人| 日韩黄色网址| 蜜桃黄片AV在线观看| 欧美熟女一区二区| 尻屄视频网站| 婷婷五月天丁香网| 欧美日韩国产成人在线| 少妇嫩搡BBBB搡BBBB| 好吊视频一区二区三区四区| 国产精品国产精品国产专区不片| 无码一级片| 国产人与禽zoz0性伦| 国产小福利| 国产一级a毛一级a毛视频在线网站) | 一本大道香蕉av久久精东影业 | 天堂资源网| AV一二区| 国产午夜精品一区二区三区嫩A| 一区二区无码高清| 在线你懂| 欧美在线观看一区| 91av在线电影| 一道本无码在线播放| 亚洲天堂视频在线| 人妻无码视频| 性猛交AAAA片免费观看直播| 亚洲男人的天堂视频网在线观看+720P | 日韩中文久久| 亚洲无码一区在线| 成人毛片在线播放| 国产毛片在线| 俺也来俺也去WWW色| 久久综合在线| 无码精品视频在线观看| 91成人做爰A片| 欧美日韩中文在线观看| 校园春色亚洲无码| 无码a区| 国产激情欧洲在线观看一区二区三区 | 午夜亚洲福利视频| 激情另类视频| 九色PORNY蝌蚪视频| 日韩人妻精品中文字幕免费| 大香久久| 欧美一级视频在线观看| 欧洲一区在线观看| 丁香五月网站| 在线黄| av午夜福利| 国产精品福利视频| 国产一级a爱做片免费☆观看| 一级A片免费黄色视频| 亚洲av资源在线观看| A片免费观看视频| 亚洲性爱视频在线观看| 91在线无码精品秘网站| 毛片网站视频| 国精产品一品二品国精| 成人网站在线| 人人妻人人爱人人| 综合色婷婷| 91视频观看| 精品人人人人| 久久亚洲综合| 一本大道东京热av无码| 黄色美女毛片| 久久久蜜桃| 国产无码久久| 杨幂操逼视频| 蜜桃av秘无码一区三| 99视频内射三四| 亚洲国产成人精品激情在线| 亚洲AV综合网| 日韩特黄| 一级A片久久久免费直播间| 欧美性爱视频免费观看| 亚洲黄色无码| 亚洲日韩毛片| 露脸老熟女91集合| 黄色片A| 国产性播放| 精品黄色片| 91九色蝌蚪| 在线观看亚洲无码视频| 91农村站街老熟女露脸| 日韩在线观看| 无码熟妇人妻无码AV在线天堂| 欧美精产国品一区二区区别| 久久久久久久| 亚洲成年人在线| 青青自拍视频| 久久久久久三级电影| h片免费网站| 午夜AV无码| 国产在线成人视频| 亚洲一级性爱| 人人插人人操| 成人香蕉| 天天添| 日韩无码毛片| 男人的天堂久久| 欧美一区二区三曲的| 亚洲香蕉av| 国产手机拍视频推荐2023| 肏屄免费视频| 国产—级a毛—a毛免费视频| 男人午夜天堂| 日本一级按摩片免费观看| 欧美激情精品| 中文字幕在线观看免费高清完整版在线观看 | 色老板免费视频| 国产AV黄| 免费网站观看www在线观看| 在线观看国产区| 久久国产一区二区三区| 波多野结衣成人视频| 毛片小电影| 久久伊人精品| 午夜探花视频| 一本色道久久综合无码人妻软件| 伊人在线观看视频| 免费看黄色毛片| 日韩成人小电影| 天天爽天天爽夜夜爽| AV无码免费一区二区三区不卡 | 精品孕妇孕交无码专区| 日韩一级黄片| 99草在线视频| 日韩激情在线| 成人18视频| 国产在线中文字幕| 国产黄色一区| 狠狠干中文字幕| 三级片在线看片AV| yjizz视频| 日韩无码久久| 爱搞搞爱干干| 江苏妇搡BBBB搡BBBB| 日韩AA片| 黄色一级a片| 人妻无码在线观看| 麻豆高清无码| www.色欲av| 人人看人人爱| 婷婷色777777| 一级a看片在线观看| 五月丁香在线视频| 亚洲AV成人一区二区三区不卡 | av三级片在线观看| 996精品在线| 国产高清无码一区二区| 午夜AV免费| 国产精品911| 狠狠干五月| 国产欧美在线视频| 开心四房播播第四婷婷| 男女操逼视频网站| 99热国产| 成人小视频在线| 蜜桃视频| 欧美成人无码一区二区三区 | 婷婷综合素质二区| 国产操比网| 中国老女人性爱视频| 久久久久久精品国产三级| 国产乱子伦一区二区三区在线观看 | 日本一区二区三区在线播放| 逼逼AV网站-日韩电影| 日韩黄色在线视频| 巨い巨乳の少妇あジed2k| 亚洲片在线观看| 精品视频在线观看| 亚洲色,天堂网| 国产三四区久久| 黄色视频导航| 新亚洲天堂男子Av-| 综合色亚洲| 欧美色成人免费在线视频| 中文字幕日本精品5| 一纹A片免费观看| 91亚洲国产成人久久精品麻豆| 99视频在线| 91麻豆免费视频| 久久毛久久久j| 精品乱伦视频| 麻豆精品国产| 躁BBB躁BBB躁BBBBB乃| 亚洲精品一区二区三区四区高清| 热久久精品| 亚洲欧洲久久| 成人爽a毛片一区二区免费| 蜜桃免费网站| 久久91视频| 欧美色爽| 在线不欧美| 伊人99re| 日本欧美在线观看高清| 日本黄色电影在线| 蜜臀99| 欧美女人操逼| 成人视频毛片| 亚洲视频播放| 先锋资源久久| 国产日批| 麻豆一区在线观看| www.在线播放| 中文字幕不卡视频| 日欧视频| 黄片免费观看视频| 波多野结衣国产区42部| 久久青青| 九九九九色| 中文字幕在线播放AV| 色情电影网站| 三级乱伦视频| 欧美成人一级| 午夜福利100理论片| 婷婷色色婷婷五月天| 射死你天天日| 先锋影音亚洲无码av| 亚洲操逼片| 国产精品国产三级囯产普通话2| 欧美在线不卡| 激情伊人五月天| 北条麻妃在线播放一区| 青青草视频| 91精品国产91久久久久久吃药 | 国产精品黄片| www.婷婷六月天| 美女中文字幕| 亚洲天堂无码在线观看| 在线免费高清无码| 天堂成人网| 三级毛片视频| 色情欧美一级A片| 久久黄色大片| 亚洲视频99| 偷拍一区二区| 国产午夜精品一区二区三区牛牛| 韩国深夜福利视频| 久久久久久穴| 国产一区在线观看视频| 51成人网站| 麻豆成人精品国产免费| 蜜桃高清无码| 中文字幕在线观看AV| 色哟哟无码精品一区二区三区| 中文字幕观看| 免费一级A片在线播放| 青青大香蕉| 国产精品无码怀孕软件| 成人网址大全| 翔田千里无码视频| 韩国无码免费| 欧美区亚洲区| 思思热思思操免费视频| 一级黄色电影免费看| 午夜视频网站| 狠狠躁夜夜躁人人爽人妻| 亚洲综合色色| 久久青草免费视频| 91视频免费观看| 不卡的av在线| 日韩欧美高清无码| 久久九九99| 真实野外打野视频| 五月婷婷视频在线观看| 波多野结衣高清无码| 男人的天堂亚洲| 色XXX| 亚洲在线中文字幕| 免费色网站| 色色色色AV| 国产久久视频| 国产精品操| 欧美日韩综合网| 四川妇BBB桑BBB桑BBB| 97精品人人妻人人| 亚洲天堂AV在线观看| 欧美日逼超碰| 国产精品久久久久久久久久久久久久 | 亚洲天堂美女| 一区二区三区不卡视频| 五月天无码在线| 国产成人久久777777| 亚洲一区二区在线| 日韩激情片| 中文字幕AV网| 屁屁影院国产第一页| 国产一级a毛一级a毛视频在线网站 | 高清无码免费在线| 一区二区三区免费在线观看| 999在线视频| 国产视频福利| 伊人视频在线观看| 九九热这里有精品| 中字无码AV| 亚洲无码一| 国产一区二区三区在线观看免费视频免费视频免费视频 | 日韩在线观看AV| 黄色录像一级片| 久久精品黄色| 友田真希一级婬片A片| 亚洲一区二区在线| 农村少妇久久久久久久| 激情无码精品| 激情乱伦网站| 97人人操| 激情五月天网址| 一本色道综合久久欧美日韩精品| 日本高清中文字幕| 波多野结衣无码视频在线观看| 国产丝袜无码| 成人精品秘久久久按摩下载 | 激情五月天综合网| 最新国产第一页| 91久久久无码国产一区二区三区 | 91嫖妓站街按摩店老熟女| 青青国产在线| 国产精品久久久久久99| 国产精品熟女| 国产高清不卡| 免费色片| 久久波多野结衣一区二区| 麻豆91精品91久久久停运原因| xxx综合网| 无码精品电影| 国产乱伦AV网站| 伊人三级网| 欧美黄色小说| 特级毛片www| 七七久久| 欧美一级A片在免费看| 四虎Av| 学生妹毛片| 日韩小黄片| 精品无码视频在线| 久草视频新| 中文字幕精品人妻在线| 国产欧美性爱| 1024在线| 国产精品免费网站| 牛牛影视一区二区| 青青草视频在线观看| 精品码一区二在线观看| 涩五月婷婷| 无码人妻AⅤ一区二区三区| 亚洲AAAAAA| 精品国产乱子伦一区二区三区最新章| 中文无码电影| 精品无码一区二区Av蜜桃| 高清在线无码视频| 亚洲精品国产精品乱玛不99 | 男人天堂婷婷| 人人天天久久| 特级大毛片| 久久三级视频| 国产www在线观看| 看一级黄色片| 中文字幕视频免费| 国产精品国产三级国产专区52| 性视频人人| 国产一级二级三级| 日韩精品成人无码免费| 人人澡超碰碰| 色色网站在线观看| 加勒比无码综合| 日逼视频| 国产一区免费| 四虎精品一区二区| 欧美人妻中文字幕| 操逼逼片| 北条麻妃九九九精品视频免费观看| 亚洲色播放| 在线中文字幕网站| 黄色成人在线免费观看| a级网站| 学生妹内射| 91在线欧美| 色男天堂| 国产一级婬女AAAA片季秀英| 99精品视频在线播放免费| 成人a片在线观看| 欧美后门菊门交3p| 午夜成人网站在线观看| 在线观看免费人成视频| 无毛片| 樱桃AV| 操逼一级片| 一本大道DVD中文字幕| 青娱乐在线视频精品| 蜜臀AV午夜精品| 亚洲视频观看| 黄色一级在线| 中国老太卖婬HD播放| 久久国产免费| 久久精品国产亚洲| 牛牛影视av老牛影视av| 中国免费XXXX18| 九色PORNY国产成人| 久久久久亚洲AV无码专区成人| 黄色在线网| 欧美日韩中国操逼打炮| 国产精品成人片| 操逼大香蕉| 人人上人人干| 中文解说AⅤ水果派| 日韩啪啪啪网站| 日韩美在线| 91在线无码精品入口电车| 欧美成人不卡| 欧美在线观看一区| 天天做天天干| 亚洲精品秘一区二区三线观看| 刘玥91精一区二区三区| jjzz国产| 日韩无码影视| 韩国三级HD中文字幕的背景音乐| 骚逼久久| 国产精品女人777777| 一本色道久久综合狠狠躁| 无码在线视频免费观看| 爱爱导航| 你懂的视频| 中文一级片| 亚洲专区视频| 国产淫语| 婷婷六月综合| 欧美操b| 国产无遮挡又黄又爽又色| 国产A级视频| 91影音先锋| 黄色视频免费观看国产| 操B视频在线播放| 四川妇搡BBBB搡BBBB| 国产女人操逼视频| 中文字幕乱伦性爱| 成人视频网站18| 国产福利AV| 欧美成人高清| 高h视频在线观看| 全国最大成人网| 操逼视频在线看| 色色色网站| 国产视频福利在线| 成人三级毛片| 黑人猛躁白人BBBBBBBBB| 久久6精品| 天天干天天射天天爽| 午夜免费网站| 18成人网站在线观看| 骚逼日本| 欧美一级三级| 成人福利视频在线| 亚洲天堂电影网| 一级乱伦网站| 男女抽插视频| 思思热在线视频播放| 人人操人人干人人| 久久婷婷久久| 香蕉网站操逼片| 麻豆91免费视频| 国产一级a毛一级a毛片视频黑人 | 加勒比日韩在线| 汇聚全球淫荡熟女| 一级黄色电影A片| 丰满人妻一区二区三区视频在线不卡 | 日韩在线中文字幕| 青青草网站在线观看| 色欲AV秘无码一区二区三区| www99精品| 永久中文字幕| 怡红院一区二区| 在线观看中文字幕一区| 高潮喷水无码| 天堂网一区二区三区| 精品成人在线观看| 丝瓜视频黄| 青草久久网| 国产免费av在线| 亚洲人成人无码.www粉色| 69国产成人综合久久精品欧美| 69成人在线| 欧美国产第一页| 蜜桃视频com.www| 国产乱伦内射视频| 国产做爰XXXⅩ久久久骚妇| 夸克看成人片一级A片| 无码电影免费观看| 成人网站www污污污网站公司| 影音先锋国产在线| 国产欧美日韩在线视频| 亚洲秘av无码一区二区| 久草性爱| 久久在线免费视频| 久久成人电影院| 国产黄A| 九九精品久久| 成人午夜激情| 2014天堂网| 欧美午夜福利视频| 国产有码| 婷婷五月丁香六月| 久久精品网| 亚洲第一网无码性色| 久久久久久久香蕉视频| 亚洲色777| 西西www444无码大胆| 一级黄色av| 午夜无码福利视频| xxxxx无码| 91原创国产内射| 91在线视频免费| 午夜探花在线观看| 日本成人电影在线观看| 久久视频国产| 中文字幕23页| jk无码| www香蕉成人片com| 久久成人精品| 黄片免费视频| 国产精品怡红院有限公司| 久久亚洲Aⅴ成人无码国产丝袜 | 免费看无码一级A片在线播放| 丁香五月av| 国产AV影视| 欧美熟妇精品一二三区| 日韩免费在线观看一区入口| jizz免费视频| 欧美国产另类| 国产在线看片| 性爱一级片| 夜夜爽妓女77777毛片A片| 在线毛片网站| 免费a片视频| 五月丁香中文字幕| 欧美九九九| 麻豆精东一区二区欧美国产| 国产欧美一区二区三区国产幕精品| 亚洲欧美日韩不卡| 欧美最猛黑A片黑人猛交蜜桃视频 色噜噜狠狠一区二区三区300部 | 亚洲美女喷水视频| 西西www444无码大胆| 超碰2021| 成人一区二区在线观看| 亚洲欧美成人在线视频| 日韩av在线电影| www.6969成人片亚洲| 国产一区二| 欧美不卡| 北条麻妃无码视频| 黄片Av| 婷婷丁香五月在线| 我要操逼网| 亚洲男女免费视频| 日韩精品一区二区三区黄冈站长 | 国产一区二区三区18| 91羞射短视频在线观看| 97爱爱视频| 精品免费在线| 亚洲电影在线| av在线观看中文字幕| 亚洲第一色网| 日本免费爱爱视频| 97人妻精品黄网站| 青青草综合视频| 少妇一级婬片内射视频| 在线免费看黄视频| 激情综合婷婷久久| 午夜成人视频| 天天射视频| 国产18欠欠欠一区二区| 亚洲成a人无码| 在线观看精品视频| 老汉AV| 亚洲A级片| 无码av网站| 中文字幕色情| 日韩成人无码特集| 第一福利导航大全| 日韩欧美国产精品综合嫩V | 伊人大香蕉电影| 五月激情综合| 亚洲色婷婷| 无码一区二区av| 91无码人妻精品一区二区三区四| 国产在线一| 亚洲天堂在线观看免费| 色色视频网站| 日韩中文字幕在线观看| 国产婷婷内射| 人人干人人操人人| 黑人巨粗进入疼哭A片| 国产理论电影在线观看| 精品视频一区二区三区| 丁香六月操| 一起操影院| 成人小视频在线| 国产A片免费| JUY-579被丈夫的上司侵犯后的第7天,我 | 免费黄色成人网站| 欧美在线观看视频一区| 欧美三级欧美三级三级| 欧美三级网站在线观看| 欧美午夜视频| 夜夜嗨老熟女AV一区二区三区| 一级艹逼| 国产精品久久一区二区三区影音先锋| 亚洲aⅤ| 国产一级a毛一级a做免费图片 | 中文字幕+乱码+中文乱码www| 中文字幕观看| 三级99| 午夜探花在线观看| 国精产品一二四区黑人| 亚洲高清无码视频在线观看| 国产91在线中日| 国产AV二区| 国产69精品久久久久久| AV在线免费观看网站| 亚洲日韩一区| 91在线无码精品秘软件| 成人毛片18| 亚洲国产精品成人久久蜜臀| 91精品电影18| 俺来俺去www色婷婷| 欧美一级a视频免费放| 日本九九视频| 成人午夜福利网站| 日韩肏屄视频在线观看| 黄色片视频日韩| 小h片| 翔田千里一区二区| av干在线| av无码不卡| 天天日天天摸| 久热精品在线观看| 日本免费高清视频在线观看一区 | 久久在线精品| 神马午夜51| 一级片黑人| 亚洲专区区免费| 精品1区| 中文字幕在线观看免费| 日韩一区二区免费看| 九九人妻| 欧美操逼视频网站| 日本黄色免费网站| 婷婷五月天免费视频| 特黄AAAAAAAAA真人毛片| 蜜桃91精品秘成人取精库| 91青青草| 欧美日韩在线视频免费播放| 91无码人妻精品一区二区蜜桃| 免费一级黄| 中文字幕免费在线看一区七区 | 超碰碰碰碰碰| 色妹子综合| 能看的操逼网站| 北条麻妃JUX-869无码播放| 亚洲无码av在线播放| 翔田千里被操120分钟| 国产精品一区二区三区不卡| 日韩成人视频在线| 特级444WWW大胆高清| 亚洲中文字幕日韩在线| www.日逼| 免费a片视频| 日韩插泄| 91视频在线观看免费大全| 西西444WWW无码精品| 日韩一区二区视频| 超碰997| 亚洲视频欧美视频| 中文字幕成人网| 啪啪视频国产| 美日韩无码视频| 99爱在线观看| 色就是色欧美成人网| 欧美成人手机在线观看| 国内成人AV| 欧美在线播放| 99视频+国产日韩欧美| 视频一区18| 久久免费黄色视频| 天天射网站| 亚洲女人在线| 欧美亚洲一区| 操美女的逼| 91青青草在线| 大肉大捧一进一出两腿| 69亚洲视频| 男人的天堂免费视频| 日韩人妻一区二区三区| 日韩AV无码专区亚洲AV紧身裤| 亚洲大逼| 性爱视频网站| 成人伊人AV| 久久一二三四| 操逼一级片| 在线观看免费高清无码| 污污污污污www网站免费观看| 精品中文字幕在线观看| 肉色超薄丝袜脚交一区二区| 一级a一级a爰片免费| 国产熟女视频| 欧美日韩一级黄片| 五月婷婷六月香| 中文字幕巨乱亚洲高清A片28| 亚洲午夜福利视频在线观看| 午夜福利久久| AV大香蕉| 蝌蚪窝在线视频免费观看| 亚洲AV成人无码精品直播在线 | 欧美做受高潮白| 国产精品无码白浆高潮| 西西4444www无码精品| 天天爽天天摸| 亚洲色久| 亚洲免费观看A∨中文| 九九热re99re6在线精品| 欧美成人综合| 国产精品成| 亚洲免费黄色电影| 亚州AV天堂| 欧美成人中文字幕在线| 午夜国产在线观看| 亚洲精品视频在线观看免费| 亚洲理论视频| 亚洲黄色片| 亚洲欧美v在线视频| 欧美日韩成人在线视频| 国产一区免费视频| 开心色情| 在线观看高清无码| 色欲成人网| 一区二区高清视频| 黄色的视频网站| 国产区欧美去区在线| 激情六月| 五月天婷婷无码| 中文在线观看视频| 玖玖91| 久久黄色大片| 色婷婷艹|