精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

前端進(jìn)階:從零實(shí)現(xiàn)單向 & 雙向鏈表

開(kāi)發(fā) 前端
鏈表是一種線(xiàn)性表數(shù)據(jù)結(jié)構(gòu),由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元素稱(chēng)為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域,另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。

[[397775]]

前言

前端工程師對(duì)于算法和數(shù)據(jù)結(jié)構(gòu)這塊的知識(shí)的掌握程度,是進(jìn)階高級(jí)工程師的非常重要的標(biāo)志之一,為了總結(jié)一下數(shù)據(jù)結(jié)構(gòu)和算法方面的知識(shí),筆者今天繼續(xù)把鏈表這一塊的知識(shí)補(bǔ)上,也作為自己知識(shí)體系的一個(gè)梳理,筆者早在去年就寫(xiě)過(guò)一篇關(guān)于使用javascript實(shí)現(xiàn)二叉樹(shù)和二叉搜索樹(shù)的文章,如果感興趣或者想進(jìn)階高級(jí)的朋友們可以參考學(xué)習(xí)一下: JavaScript 中的二叉樹(shù)以及二叉搜索樹(shù)的實(shí)現(xiàn)及應(yīng)用.

你將收獲

  • 鏈表的概念和應(yīng)用
  • 原生javascript實(shí)現(xiàn)一條單向鏈表
  • 原生javascript實(shí)現(xiàn)一條個(gè)雙單向鏈表
  • 鏈表和數(shù)組的對(duì)比及優(yōu)缺點(diǎn)

正文

1. 鏈表的概念和應(yīng)用

鏈表是一種線(xiàn)性表數(shù)據(jù)結(jié)構(gòu),由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元素稱(chēng)為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域,另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。

以上概念用圖表示為以下結(jié)構(gòu):

鏈表是非連續(xù)的,所以說(shuō)從底層存儲(chǔ)結(jié)構(gòu)上看,它不需要一整塊連續(xù)的存儲(chǔ)空間,而是通過(guò)“指針”將一組零散的數(shù)據(jù)單元串聯(lián)起來(lái)成為一個(gè)整體。鏈表也有幾種不同的類(lèi)型:?jiǎn)蜗蜴湵?,雙向鏈表,循環(huán)鏈表。上圖就是一種單向鏈表。由其定義不難發(fā)現(xiàn)雙向鏈表無(wú)非就是每個(gè)節(jié)點(diǎn)加上了前后節(jié)點(diǎn)的指針引用,如下圖所示:

那什么是循環(huán)鏈表呢?循環(huán)鏈表本質(zhì)上是一種特殊的單向鏈表,唯一的區(qū)別就在于它的尾結(jié)點(diǎn)指向了鏈表的頭結(jié)點(diǎn),這樣首尾相連,形成了一個(gè)環(huán),所以叫做循環(huán)鏈表。如下圖所示:

當(dāng)然我們還可以擴(kuò)展出雙向循環(huán)鏈表,這里就不一一舉例了??傊湵斫Y(jié)構(gòu)在計(jì)算機(jī)底層語(yǔ)言中應(yīng)用的比較多,當(dāng)我們?cè)谟酶呒?jí)語(yǔ)言做編程時(shí)可能不會(huì)察覺(jué),比如我們用javascript敲js的時(shí)候,其實(shí)我們?cè)谏钊肓私怄湵碇笪覀兙蜁?huì)發(fā)現(xiàn)鏈表有很多應(yīng)用場(chǎng)景,比如LRU 緩存淘汰,最近消息推送等。

舉個(gè)更接地氣的,當(dāng)我們?cè)谟肞S畫(huà)圖時(shí)軟件提供了一個(gè)動(dòng)作面板,可以記錄用戶(hù)之前的操作記錄,并批量執(zhí)行動(dòng)作,或者當(dāng)我們?cè)谑褂镁庉嬈鲿r(shí)的回退撤銷(xiāo)功能等,用鏈表結(jié)構(gòu)來(lái)存儲(chǔ)狀態(tài)信息還是比較方便的。

最近比較火的react hooks API,其結(jié)構(gòu)也是一個(gè)鏈表型的數(shù)據(jù)結(jié)構(gòu),所以學(xué)習(xí)鏈表還是非常有幫助的。讀到這里可能還是有點(diǎn)懵,接下來(lái)我們先用js實(shí)現(xiàn)一個(gè)鏈表,這樣有助于理解鏈表的本質(zhì),后面筆者會(huì)總結(jié)一下鏈表和數(shù)組的對(duì)比以及優(yōu)劣勢(shì),方便大家對(duì)鏈表有一個(gè)更加直觀的認(rèn)識(shí)。

2.原生javascript實(shí)現(xiàn)一條單向鏈表

在上面一節(jié)介紹的鏈表結(jié)構(gòu)中大家可能對(duì)鏈表有了初步的認(rèn)識(shí),因?yàn)閖avascript中沒(méi)有鏈表的數(shù)據(jù)結(jié)構(gòu),為了模擬鏈表結(jié)構(gòu),我們可以通過(guò)js面向?qū)ο蟮姆绞綄?shí)現(xiàn)一個(gè)鏈表結(jié)構(gòu)及其API,具體設(shè)計(jì)如下:

有了以上需求點(diǎn)之后,這個(gè)鏈表才是基本可用的鏈表,那么我們一步步來(lái)實(shí)現(xiàn)它吧。

2.1 定義鏈表結(jié)構(gòu)

為了實(shí)現(xiàn)鏈表以及鏈表的操作,首先我們需要先定義鏈表的基本結(jié)構(gòu),第一步就是定義節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。我們知道一個(gè)節(jié)點(diǎn)會(huì)有自己的值以及指向下一個(gè)節(jié)點(diǎn)的引用,所以可以這樣定義節(jié)點(diǎn):

  1. let Node = function(el) { 
  2.       this.el = el; 
  3.       this.next = null
  4.  } 

接下來(lái)我們定義一下鏈表的基本骨架:

  1. // 單向鏈表, 每一個(gè)元素都有一個(gè)存儲(chǔ)元素自身的節(jié)點(diǎn)和一個(gè)指向下一個(gè)元素引用的節(jié)點(diǎn)組成 
  2. function linkedList() { 
  3.   let Node = function(el) { 
  4.       this.el = el; 
  5.       this.next = null
  6.   } 
  7.   let length = 0 
  8.   let head = null  // 用來(lái)存儲(chǔ)第一個(gè)元素的引用 
  9.  
  10.   // 尾部添加元素 
  11.   this.append = (el) => {}; 
  12.   //插入元素 
  13.   this.insert = (pos, el) => {}; 
  14.   // 移除指定位置的元素 
  15.   this.removeAt = (pos) => {}; 
  16.   // 移除指定節(jié)點(diǎn) 
  17.   this.remove = (el) => {}; 
  18.   // 查詢(xún)節(jié)點(diǎn)所在位置 
  19.   this.indexOf = (el) => {}; 
  20.   // 判斷鏈表是否為空 
  21.   this.isEmpty = () => {}; 
  22.   // 返回鏈表長(zhǎng)度 
  23.   this.size = () => {}; 
  24.   // 將鏈表轉(zhuǎn)化為數(shù)組返回 
  25.   this.toArray = () => {}; 

由以上代碼我們可以知道鏈表的初始長(zhǎng)度為0,頭部元素為null,接下來(lái)我們實(shí)現(xiàn)添加節(jié)點(diǎn)的功能。

2.2 實(shí)現(xiàn)添加節(jié)點(diǎn)

追加節(jié)點(diǎn)的時(shí)候首先需要知道頭部節(jié)點(diǎn)是否存在,如果不存在直接賦值,存在的話(huà)則從頭部開(kāi)始遍歷,直到找到下一個(gè)節(jié)點(diǎn)為空的節(jié)點(diǎn),再賦值,并將鏈表長(zhǎng)度+1,代碼如下:

  1. // 尾部添加元素 
  2. this.append = (el) => { 
  3.     let node = new Node(el), 
  4.         current
  5.     if(!head) { 
  6.       head = node 
  7.     }else { 
  8.       current = head; 
  9.       while(current.next) { 
  10.         current = current.next
  11.       } 
  12.       current.next = node; 
  13.     } 
  14.     length++ 
  15. }; 

2.3 實(shí)現(xiàn)插入節(jié)點(diǎn)

實(shí)現(xiàn)插入節(jié)點(diǎn)邏輯首先我們要考慮邊界條件,如果插入的位置在頭部或者比尾部位置還大,我們就沒(méi)必要從頭遍歷一遍處理了,這樣可以提高性能,所以我們可以這樣處理:

  1. //插入元素 
  2. this.insert = (pos, el) => { 
  3.     if(pos >=0 && pos <= length) { 
  4.       let node = new Node(el), 
  5.           previousNode = null
  6.           current = head, 
  7.           curIdx = 0; 
  8.       if(pos === 0) { 
  9.         node.next = current
  10.         head = node; 
  11.       }else { 
  12.         while(curIdx++ < pos) { 
  13.           previousNode = current
  14.           current = current.next
  15.         } 
  16.         node.next = current
  17.         previousNode.next = node; 
  18.         length++; 
  19.         return true 
  20.       } 
  21.     }else { 
  22.       return false 
  23.     } 
  24. }; 

2.4 根據(jù)節(jié)點(diǎn)的值查詢(xún)節(jié)點(diǎn)位置

根據(jù)節(jié)點(diǎn)的值查詢(xún)節(jié)點(diǎn)位置實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,我們只要從頭開(kāi)始遍歷,然后找到對(duì)應(yīng)的值之后記錄一下索引即可:

  1. // 查詢(xún)節(jié)點(diǎn)所在位置 
  2. this.indexOf = (el) => { 
  3.     let idx = -1, 
  4.         curIdx = -1, 
  5.         current = head; 
  6.     while(current) { 
  7.       idx++ 
  8.       if(current.el === el) { 
  9.         curIdx = idx 
  10.         break; 
  11.       } 
  12.       current = current.next
  13.     } 
  14.     return curIdx 
  15. }; 

這里我們之所以要用idx和curIdx兩個(gè)變量來(lái)處理,是因?yàn)槿绻脩?hù)傳入的值不在鏈表里,那么idx的值就會(huì)有問(wèn)題,所以用curIdx來(lái)保證準(zhǔn)確性。

2.5 移除指定位置的節(jié)點(diǎn)

移除指定位置的節(jié)點(diǎn)也需要判斷一下邊界條件,可插入節(jié)點(diǎn)類(lèi)似,但要注意移除之后一定要將鏈表長(zhǎng)度-1,代碼如下:

  1. // 移除指定位置的元素 
  2. this.removeAt = (pos) => { 
  3.     // 檢測(cè)邊界條件 
  4.     if(pos >=0 && pos < length) { 
  5.       let previousNode = null
  6.                current = head, 
  7.                curIdx = 0; 
  8.       if(pos === 0) { 
  9.         // 如果pos為第一個(gè)元素 
  10.         head = current.next 
  11.       }else { 
  12.         while(curIdx++ < pos) { 
  13.           previousNode = current
  14.           current = current.next
  15.         } 
  16.         previousNode.next = current.next
  17.       } 
  18.       length --; 
  19.       return current.el 
  20.     }else { 
  21.       return null 
  22.     } 
  23. }; 

2.6 移除指定節(jié)點(diǎn)

移除指定節(jié)點(diǎn)實(shí)現(xiàn)非常簡(jiǎn)單,我們只需要利用之前實(shí)現(xiàn)好的查找節(jié)點(diǎn)先找到節(jié)點(diǎn)的位置,然后再用實(shí)現(xiàn)過(guò)的removeAt即可,代碼如下:

  1. // 移除指定節(jié)點(diǎn) 
  2. this.remove = (el) => { 
  3.   let idx = this.indexOf(el); 
  4.   this.removeAt(idx); 
  5. }; 

2.7 獲取節(jié)點(diǎn)長(zhǎng)度

這里比較簡(jiǎn)單,直接上代碼:

  1. // 返回鏈表長(zhǎng)度 
  2. this.size = () => { 
  3.   return length 
  4. }; 

2.8 判斷鏈表是否為空

判斷鏈表是否為空我們只需要判斷長(zhǎng)度是否為零即可:

  1. // 返回鏈表長(zhǎng)度 
  2. this.size = () => { 
  3.   return length 
  4. }; 

2.9 打印節(jié)點(diǎn)

打印節(jié)點(diǎn)實(shí)現(xiàn)方式有很多,大家可以按照自己喜歡的格式打印,這里筆者直接將其打印為數(shù)組格式輸出,代碼如下:

  1. // 將鏈表轉(zhuǎn)化為數(shù)組返回 
  2. this.toArray = () => { 
  3.     let current = head, 
  4.         results = []; 
  5.     while(current) { 
  6.       results.push(current.el); 
  7.       current = current.next
  8.     } 
  9.     return results 
  10. };  

這樣,我們的單向鏈表就實(shí)現(xiàn)了,那么我們可以這么使用:

  1. let link = new linkedList() 
  2. // 添加節(jié)點(diǎn) 
  3. link.append(1) 
  4. link.append(2) 
  5. // 查找節(jié)點(diǎn) 
  6. link.indexOf(2) 
  7. // ... 

3.原生javascript實(shí)現(xiàn)一條個(gè)雙單向鏈表

有了單向鏈表的實(shí)現(xiàn)基礎(chǔ),實(shí)現(xiàn)雙向鏈表也很簡(jiǎn)單了,我們無(wú)非要關(guān)注的是雙向鏈表的節(jié)點(diǎn)創(chuàng)建,這里筆者實(shí)現(xiàn)一個(gè)例子供大家參考:

  1. let Node = function(el) { 
  2.       this.el = el; 
  3.       this.previous = null
  4.       this.next = null
  5.  } 
  6. let length = 0 
  7. let head = null  // 用來(lái)存儲(chǔ)頭部元素的引用 
  8. let tail = null  // 用來(lái)存儲(chǔ)尾部元素的引用 

由代碼可知我們?cè)诠?jié)點(diǎn)中會(huì)有上一個(gè)節(jié)點(diǎn)的引用以及下一個(gè)節(jié)點(diǎn)的引用,同時(shí)這里筆者添加了頭部節(jié)點(diǎn)和尾部節(jié)點(diǎn)方便大家操作。大家可以根據(jù)自己的需求實(shí)現(xiàn)雙向鏈表的功能,這里筆者提供一份自己實(shí)現(xiàn)的代碼,可以參考交流一下:

  1. // 雙向鏈表, 每一個(gè)元素都有一個(gè)存儲(chǔ)元素自身的節(jié)點(diǎn)和指向上一個(gè)元素引用以及下一個(gè)元素引用的節(jié)點(diǎn)組成 
  2. function doubleLinkedList() { 
  3.   let Node = function(el) { 
  4.       this.el = el; 
  5.       this.previous = null
  6.       this.next = null
  7.   } 
  8.   let length = 0 
  9.   let head = null  // 用來(lái)存儲(chǔ)頭部元素的引用 
  10.   let tail = null  // 用來(lái)存儲(chǔ)尾部元素的引用 
  11.  
  12.   // 尾部添加元素 
  13.   this.append = (el) => { 
  14.     let node = new Node(el) 
  15.     if(!head) { 
  16.       head = node 
  17.     }else { 
  18.       tail.next = node; 
  19.       node.previous = tail; 
  20.     } 
  21.     tail = node; 
  22.     length++ 
  23.   }; 
  24.   // 插入元素 
  25.   this.insert = (pos, el) => { 
  26.     if(pos >=0 && pos < length) { 
  27.       let node = new Node(el); 
  28.       if(pos === length - 1) { 
  29.         // 在尾部插入 
  30.         node.previous = tail.previous; 
  31.         node.next = tail; 
  32.         tail.previous = node; 
  33.         length++; 
  34.         return true 
  35.       } 
  36.       let current = head, 
  37.           i = 0; 
  38.       while(i < pos) { 
  39.         current = current.next
  40.         i++ 
  41.       } 
  42.       node.next = current
  43.       node.previous = current.previous; 
  44.       current.previous.next = node; 
  45.       current.previous = node; 
  46.       length ++; 
  47.       return true     
  48.     }else { 
  49.       throw new RangeError(`插入范圍有誤`) 
  50.     } 
  51.   }; 
  52.   // 移除指定位置的元素 
  53.   this.removeAt = (pos) => { 
  54.     // 檢測(cè)邊界條件 
  55.     if(pos < 0 || pos >= length) { 
  56.       throw new RangeError(`刪除范圍有誤`) 
  57.     }else { 
  58.       if(length) { 
  59.         if(pos === length - 1) { 
  60.           // 如果刪除節(jié)點(diǎn)位置為尾節(jié)點(diǎn),直接刪除,節(jié)省查找時(shí)間 
  61.           let previous = tail.previous; 
  62.           previous.next = null
  63.           length --; 
  64.           return tail.el 
  65.         }else { 
  66.           let current = head, 
  67.               previous = null
  68.               next = null
  69.               i = 0; 
  70.           while(i < pos) { 
  71.             current = current.next 
  72.             i++ 
  73.           } 
  74.           previous = current.previous; 
  75.           next = current.next
  76.           previous.next = next
  77.           length --; 
  78.           return current.el 
  79.         } 
  80.       }else { 
  81.         return null 
  82.       } 
  83.     } 
  84.   }; 
  85.   // 移除指定節(jié)點(diǎn) 
  86.   this.remove = (el) => { 
  87.     let idx = this.indexOf(el); 
  88.     this.removeAt(idx); 
  89.   }; 
  90.   // 查詢(xún)指定位置的鏈表元素 
  91.   this.get = (index) => { 
  92.     if(index < 0 || index >= length) { 
  93.       return undefined 
  94.     }else { 
  95.       if(length) { 
  96.         if(index === length - 1) { 
  97.           return tail.el 
  98.         } 
  99.         let current = head, 
  100.             i = 0; 
  101.         while(i < index) { 
  102.           current = current.next 
  103.           i++ 
  104.         } 
  105.         return current.el 
  106.       }else { 
  107.         return undefined 
  108.       } 
  109.     } 
  110.   } 
  111.   // 查詢(xún)節(jié)點(diǎn)所在位置 
  112.   this.indexOf = (el) => { 
  113.     let idx = -1, 
  114.         current = head, 
  115.         curIdx = -1; 
  116.     while(current) { 
  117.       idx++ 
  118.       if(current.el === el) { 
  119.         curIdx = idx; 
  120.         break; 
  121.       } 
  122.       current = current.next
  123.     } 
  124.     return curIdx 
  125.   }; 
  126.   // 判斷鏈表是否為空 
  127.   this.isEmpty = () => { 
  128.     return length === 0 
  129.   }; 
  130.   // 返回鏈表長(zhǎng)度 
  131.   this.size = () => { 
  132.     return length 
  133.   }; 
  134.   // 將鏈表轉(zhuǎn)化為數(shù)組返回 
  135.   this.toArray = () => { 
  136.     let current = head, 
  137.         results = []; 
  138.     while(current) { 
  139.       results.push(current.el); 
  140.       current = current.next
  141.     } 
  142.     return results 
  143.   }; 

4.鏈表和數(shù)組的對(duì)比及優(yōu)缺點(diǎn)

實(shí)現(xiàn)完鏈表之后我們會(huì)對(duì)鏈表有更深入的認(rèn)知,接下來(lái)我們進(jìn)一步分析鏈表的優(yōu)缺點(diǎn)。筆者將從3個(gè)維度來(lái)帶大家分析鏈表的性能情況:

  • 插入刪除性能
  • 查詢(xún)性能
  • 內(nèi)存占用

我們先看看插入和刪除的過(guò)程:

由上圖可以發(fā)現(xiàn),鏈表的插入、刪除數(shù)據(jù)效率非常高,只需要考慮相鄰結(jié)點(diǎn)的指針變化,因?yàn)椴恍枰苿?dòng)其他節(jié)點(diǎn),時(shí)間復(fù)雜度是 O(1)。

再來(lái)看看查詢(xún)過(guò)程:

我們對(duì)鏈表進(jìn)行每一次查詢(xún)時(shí),都需要從鏈表的頭部開(kāi)始找起,一步步遍歷到目標(biāo)節(jié)點(diǎn),這個(gè)過(guò)程效率是非常低的,時(shí)間復(fù)雜度是 O(n)。這方面我們使用數(shù)組的話(huà)效率會(huì)更高一點(diǎn)。

我們?cè)倏纯磧?nèi)存占用。鏈表的內(nèi)存消耗比較大,因?yàn)槊總€(gè)結(jié)點(diǎn)除了要存儲(chǔ)數(shù)據(jù)本身,還要儲(chǔ)存前后結(jié)點(diǎn)的地址。但是好處是可以動(dòng)態(tài)分配內(nèi)存。

另一方面,對(duì)于數(shù)組來(lái)說(shuō),也存在一些缺點(diǎn),比如數(shù)組必須占用整塊、連續(xù)的內(nèi)存空間,如果聲明的數(shù)組數(shù)據(jù)量過(guò)大,可能會(huì)導(dǎo)致“內(nèi)存不足”。其次就是數(shù)組一旦需要擴(kuò)容,會(huì)重新申請(qǐng)連續(xù)的內(nèi)存空間,并且需要把上一次的數(shù)組數(shù)據(jù)全部copy到新的內(nèi)存空間中。

綜上所述,當(dāng)我們的數(shù)據(jù)存在頻繁的插入刪除操作時(shí),我們可以采用鏈表結(jié)構(gòu)來(lái)存儲(chǔ)我們的數(shù)據(jù),如果涉及到頻繁查找的操作,我們可以采用數(shù)組來(lái)處理。實(shí)際工作中很多底層框架的封裝都是采用組合模式進(jìn)行設(shè)計(jì),一般純粹采用某種數(shù)據(jù)結(jié)構(gòu)的比較少,所以具體還是要根據(jù)所處環(huán)境進(jìn)行適當(dāng)?shù)姆桨冈O(shè)計(jì)。

 

責(zé)任編輯:姜華 來(lái)源: 趣談前端
相關(guān)推薦

2024-11-04 06:00:00

redis雙向鏈表

2010-02-06 09:46:46

C++單向鏈表

2024-11-22 15:00:00

開(kāi)源Redis鏈表

2013-12-18 13:30:19

Linux運(yùn)維Linux學(xué)習(xí)Linux入門(mén)

2025-04-18 00:00:00

MCPSSEHTTP

2021-08-15 22:52:30

前端H5拼圖

2020-09-24 11:46:03

Promise

2011-02-28 18:19:40

無(wú)線(xiàn)

2015-10-12 16:37:39

前端編碼雙向編譯

2013-07-01 15:06:04

2021-02-19 23:07:02

Vue綁定組件

2023-11-07 14:30:28

Python開(kāi)發(fā)

2024-08-28 08:09:13

contextmetrics類(lèi)型

2023-01-07 08:09:41

零代碼Dooring組件

2022-12-26 00:51:33

雙向鏈表二叉搜索樹(shù)

2022-02-13 23:00:48

前端微前端qiankun

2020-05-20 22:37:42

HTTPSSSL雙向驗(yàn)證

2025-07-11 09:10:00

AI框架訓(xùn)練

2024-05-31 08:53:56

2020-10-18 17:09:14

前端開(kāi)發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

精品嫩草影院| av日韩国产| 国产一区二区在线免费观看| 美日韩精品视频免费看| 欧美夫妇交换xxx| 欧美最新精品| 无码 人妻 在线 视频| 91麻豆精品国产91久久久更新资源速度超快 | 久久久久久一级片| 国产精品一区二区女厕厕| 26uuu成人网| 羞羞色国产精品网站| 欧美无乱码久久久免费午夜一区| 色哟哟免费网站| 久久精品色图| 国产白丝精品91爽爽久久| 欧美在线激情网| 青娱乐国产盛宴| 日本道不卡免费一区| 欧美精品一区视频| 奇米影音第四色| 在线免费av资源| 亚洲精品视频在线观看网站| 久久精品99| 草逼视频免费看| 毛片av一区二区| 欧美洲成人男女午夜视频| 爱爱视频免费在线观看| 国产一区二区三区探花| 精品国产百合女同互慰| 伊人色在线观看| 电影天堂国产精品| 午夜精彩视频在线观看不卡| 天天在线免费视频| a√在线中文网新版址在线| 成a人片国产精品| 91黄色国产视频| 亚洲在线视频播放| 玖玖玖国产精品| 97在线观看视频| 国产亚洲精品av| 这里只有精品在线| xvideos国产精品| 欧美成人短视频| 精品国产一级毛片| 亚洲午夜小视频| 欧美性xxxx图片| 看全色黄大色大片免费久久久| 777欧美精品| 欧美日韩精品区别| 日本免费成人| 欧美日本国产一区| 香蕉视频999| 日韩一区中文| 欧美日韩高清一区二区| 亚洲黄色av网址| 美女色狠狠久久| 欧美在线免费视屏| 一区二区三区国产免费| 国产综合av| 欧美亚洲丝袜传媒另类| 久久精品香蕉视频| 亚洲成人短视频| 欧美色网站导航| 黄色小视频免费网站| 欧美日韩破处视频| 在线播放中文一区| 91亚洲一线产区二线产区 | 久久精精品视频| 九色在线视频| 国产精品美女www爽爽爽| 中文字幕一区二区三区乱码| 含羞草www国产在线视频| 亚洲欧美日韩国产另类专区| 国产人妻互换一区二区| 伊人电影在线观看| 亚洲午夜久久久久中文字幕久| 国产精品久久国产| 中文在线中文资源| 欧美亚洲尤物久久| 亚洲精品一区二区18漫画| 澳门成人av| 亚洲欧美日韩中文视频| av免费播放网站| 亚洲影视一区二区三区| 久久全球大尺度高清视频| 国产又大又黄又粗| 理论电影国产精品| 国产二区不卡| 国产在线日本| 亚洲欧美日韩成人高清在线一区| 麻豆tv在线播放| 成人国产激情| 欧美大片免费久久精品三p| 久久久国产精品无码| 欧美艳星介绍134位艳星| 久久国产精品久久国产精品| 日韩av片在线播放| 久久精品国产99国产精品| 91精品国产一区二区三区动漫| 午夜av免费观看| 中文字幕一区二区三区在线不卡| 337p亚洲精品色噜噜狠狠p| 原纱央莉成人av片| 欧美一区二区三区视频| 亚洲国产欧美视频| 欧美日韩综合| 国产精品日韩欧美| 人妻精品无码一区二区| 国产欧美日韩不卡免费| 国产xxxx振车| 久久69成人| 精品视频久久久久久久| 国产suv精品一区二区68| 香蕉久久国产| 国产乱码精品一区二区三区不卡| 日本在线免费中文字幕| 日韩欧美一区二区三区| 在线观看欧美一区二区| 久久影视一区| 国产成人精品久久亚洲高清不卡| 亚洲av永久无码国产精品久久 | 中文字幕另类日韩欧美亚洲嫩草| 国产日韩欧美一区在线| 97se视频在线观看| 最新97超碰在线| 日韩欧美精品在线观看| 性囗交免费视频观看| 欧美一区精品| 国产日本欧美一区| av基地在线| 色乱码一区二区三区88| 熟妇高潮一区二区| 欧美.www| 91探花福利精品国产自产在线| 极品白浆推特女神在线观看| 午夜国产不卡在线观看视频| 性生活在线视频| 88国产精品视频一区二区三区| 国产精品99久久久久久白浆小说| 亚洲色图狠狠干| 婷婷久久综合九色综合绿巨人| 国产探花在线观看视频| 午夜精品毛片| 91精品视频免费| 免费av在线网址| 欧美日本在线视频| 蜜桃视频最新网址| 精品中文字幕一区二区小辣椒| 西游记1978| 免费视频观看成人| 日韩在线观看免费全集电视剧网站| 波多野结衣mp4| 欧美国产精品中文字幕| 老头吃奶性行交视频| 狠狠操综合网| 国产精品美女视频网站| av一区在线观看| 制服.丝袜.亚洲.另类.中文| 伊人久久久久久久久久久久久久| 狠狠色丁香久久婷婷综合丁香| 一区二区不卡视频| 国产日韩中文在线中文字幕| 美女av一区二区| 色呦呦中文字幕| 色综合久久久久综合体桃花网| 成人性生交大免费看| 日韩二区三区四区| 日本福利视频导航| 一区二区网站| 欧美性一区二区三区| 黄色在线观看网| 欧美日韩精品一区二区| 亚洲伦理一区二区三区| 国产精品18久久久久久久网站| 欧美黑人在线观看| 亚洲人成亚洲精品| 国产精品色悠悠| 污污在线观看| 日韩电影免费观看中文字幕| 黄色网址中文字幕| 亚洲黄色免费电影| 波多野结衣先锋影音| 日韩电影在线免费看| 中文精品一区二区三区| 一本色道69色精品综合久久| 97精品伊人久久久大香线蕉| 国产在线播放av| 欧美一个色资源| 亚洲图片在线视频| 亚洲日本va午夜在线影院| 亚洲av无码一区东京热久久| 免费视频久久| 亚洲国产精品女人| 夜夜躁狠狠躁日日躁2021日韩| 国产精品亚洲视频在线观看| 四虎av在线| 一区二区三区无码高清视频| 99久久亚洲精品日本无码| 午夜亚洲国产au精品一区二区 | 亚洲精品成人精品456| 亚洲av片不卡无码久久| 国产福利一区二区| 日韩欧美xxxx| 精品99视频| 亚洲一二三区精品| 色先锋久久影院av| 91成人免费观看| 黄色精品视频网站| **欧美日韩vr在线| 在线免费观看的av| 最近免费中文字幕视频2019| 香蕉视频黄色片| 日韩精品在线网站| 一区二区三区亚洲视频| 色综合天天综合色综合av| 久艹视频在线观看| 亚洲欧美中日韩| 免费看黄色的视频| 99精品视频在线播放观看| 久久综合在线观看| 老司机精品视频导航| 男人操女人逼免费视频| 中文字幕午夜精品一区二区三区| 日韩.欧美.亚洲| 亚洲男人都懂第一日本| 国产传媒欧美日韩| 日韩在线观看一区二区三区| 国产精品直播网红| 日本成人片在线| 日韩av大片在线| 欧美aa一级| 2019最新中文字幕| а√天堂中文在线资源8| 欧美人在线视频| 亚洲小说区图片区都市| 日韩少妇与小伙激情| 成年人视频在线免费观看| 国产午夜精品久久久| 手机在线精品视频| 亚洲精品在线电影| 亚洲精品字幕在线| 欧美va日韩va| 亚洲国产精品久久久久爰性色 | 国产成人精品一区二区| 亚洲人体视频| 日本中文字幕成人| 日本欧美韩国| 国产精品香蕉av| 亚洲人成777| 亚洲综合大片69999| 国语精品视频| 丁香婷婷久久久综合精品国产| 久久伊人影院| 翡翠波斯猫1977年美国| 999久久精品| 精品一区在线播放| 免费看成人哺乳视频网站| 日韩精品久久久| 久久一区二区三区电影| 国产卡一卡二在线| 国模大胆一区二区三区| 人体内射精一区二区三区| 99精品福利视频| 可以免费观看av毛片| 蜜桃av一区二区在线观看| 色婷婷一区二区三区av免费看| 蜜桃91丨九色丨蝌蚪91桃色| 人人干人人干人人| 国产精品一区二区x88av| 动漫av在线免费观看| 99精品视频一区二区三区| 干b视频在线观看| 国产精品超碰97尤物18| 中文字幕在线有码| 欧美日韩国产中字| 中文字幕久久网| 日韩区在线观看| 亚洲日本中文字幕在线| 在线日韩精品视频| 婷婷av在线| 欧美在线视频观看| 日韩在线电影| 久久99精品久久久久久久久久 | 成人午夜免费剧场| 中文亚洲欧美| 爱爱爱爱免费视频| jizz一区二区| 欧美88888| 五月天精品一区二区三区| 中文在线a天堂| 精品成人佐山爱一区二区| 国产在线视频福利| 久久99青青精品免费观看| 不卡福利视频| 亚洲已满18点击进入在线看片 | 国产精品18p| 在线观看av不卡| 国产成人三级在线观看视频| 亚洲色图国产精品| 黄色污污视频在线观看| 国产精品偷伦免费视频观看的| 国产精品调教视频| 亚洲在线播放电影| 夜久久久久久| 三区视频在线观看| 久久亚洲二区三区| 久草成人在线视频| 欧美丰满少妇xxxxx高潮对白| 亚洲日本香蕉视频| 久久久久成人网| 亚洲欧美一级| 亚洲精品久久区二区三区蜜桃臀| 亚洲人成久久| 欧美激情第四页| 中文字幕第一页久久| 三级黄色在线视频| 日韩午夜三级在线| 亚洲1卡2卡3卡4卡乱码精品| 欧美一级片一区| jazzjazz国产精品麻豆| 一级黄色片播放| 麻豆视频观看网址久久| a毛片毛片av永久免费| 亚洲成人一区二区在线观看| 99精品国产99久久久久久97| 中文字幕在线亚洲| 日韩欧美精品电影| 蜜桃麻豆91| 99精品视频免费观看| aaa黄色大片| 一区二区三区四区五区视频在线观看| 中文字幕日韩国产| 亚洲午夜av电影| 男人皇宫亚洲男人2020| 国内精品国语自产拍在线观看| 午夜欧美精品| 波多野结衣网页| 亚洲欧美二区三区| 国产美女明星三级做爰| 久久精品视频免费播放| 免费一区二区三区四区| 亚洲欧洲精品一区二区三区波多野1战4| 另类av一区二区| 亚洲 小说 欧美 激情 另类| 五月婷婷另类国产| 日本aaa在线观看| 清纯唯美亚洲激情| 久久99蜜桃| 日日碰狠狠丁香久燥| 国产欧美视频一区二区| 中文字幕永久在线| 中文字幕久热精品在线视频| 国产精品久久亚洲不卡| 亚洲国产日韩美| 久草热8精品视频在线观看| 老司机精品免费视频| 欧美久久一二三四区| 黄色动漫在线| aa日韩免费精品视频一| 亚洲免费观看| wwwwww日本| 欧美亚洲综合网| 麻豆系列在线观看| 成人免费视频网站入口| 亚洲激情一区| 熟女俱乐部一区二区| 欧美日韩亚州综合| 尤物在线网址| 精品日韩美女| 奇米四色…亚洲| 天堂网avav| 亚洲第一页自拍| 99re久久| 亚洲精品天堂成人片av在线播放| 成人看片黄a免费看在线| 国产无遮挡呻吟娇喘视频| 一区二区在线免费视频| 欧美专区视频| 国产免费黄视频| 日韩一区中文字幕| 四虎在线视频免费观看| 国产成人激情小视频| 欧美阿v一级看视频| 中文字幕日韩三级片| 欧美视频在线不卡| 肉肉视频在线观看| 欧美日韩在线高清| 国产精品一区专区| 丁香六月婷婷综合| 操人视频在线观看欧美| 欧美黑白配在线| 日韩在线不卡一区| 精品动漫一区二区三区| 老司机午夜在线| 久久久水蜜桃| 国产伦精品一区二区三区视频青涩| 国产成人在线视频观看| 久久久精品久久久| 国产欧美日韩在线观看视频|