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

圖解 | 從武俠角度探究STL排序算法的奧秘

開發 前端 算法
眾所周知STL是借助于模板化來支撐數據結構和算法的通用化,通用化對于C++使用者來說已經很驚喜了,但是如果你看看STL開發者強大的陣容就意識到STL給我們帶來的驚喜絕不會止步于通用化,強悍的性能和效率是STL的更讓人驚艷的地方。

[[410325]]

本文轉載自微信公眾號「后端研究所」,作者大白斯基。轉載本文請聯系后端研究所公眾號。

 前言

今天來看一下STL中的sort算法的底層實現和代碼技巧。

眾所周知STL是借助于模板化來支撐數據結構和算法的通用化,通用化對于C++使用者來說已經很驚喜了,但是如果你看看STL開發者強大的陣容就意識到STL給我們帶來的驚喜絕不會止步于通用化,強悍的性能和效率是STL的更讓人驚艷的地方。

STL極致表現的背后是大牛們爐火純青的編程技藝和追求極致的工匠精神的切實體現。

筆者能力所限,只能踏著前人的肩膀來和大家一起看看STL中sort算法的背后究竟隱藏著什么,是不是有種《走進科學》的既視感,讓我們開始今天的sort算法旅程吧!

內省式哲學

在了解sort算法的實現之前先來看一個概念:內省式排序,說實話筆者的語文水平確實一般,對于這個詞語用在排序算法上總覺得不通透,那就研究一下吧!

內省式排序英文是Introspective Sort,其中單詞introspective是內省型的意思,還是不太明白,繼續搜索,看一下百度百科對這個詞條的解釋:

內省(Introspection )在心理學中,它是心理學基本研究方法之一。內省法又稱自我觀察法。它是發生在內部的,我們自己能夠意識到的主觀現象。也可以說是對于自己的主觀經驗及其變化的觀察。

正因為它的主觀性,內省法自古以來就成為心理學界長期的爭論。另外內省也可看作自我反省,也是儒家強調的自我思考。從這個角度說可以應用于計算機領域,如Java內省機制和cocoa內省機制。

好家伙,原來內省是個心理學名詞,到這里筆者有些感覺了,內省就是自省、自我思考、根據自己的主觀經驗來觀察變化做出調整,而不是把希望寄托于外界,而是自己的經驗和能力。

通俗點說,內省算法不挑數據集,盡量針對每種數據集都能給定對應的處理方法,讓排序都能有時間保證。

寫到這里,讓筆者腦海浮現了《倚天屠龍記》里面張無忌光明頂大戰六大門派的場景,無論敵人多么強悍或者羸弱,我都按照自己的路子應對。

他強由他強,清風拂山崗;

他橫由他橫,明月照大江;

他自狠來他自惡,我自一口真氣足。

---《九陽真經》達摩

哲學啊,確實這樣的,我們切換到排序的角度來看看內省是怎么樣的過程。

筆者理解的內省式排序算法就是不依賴于外界數據的好壞多寡,而是根據自己針對每種極端場景下做出相應的判斷和決策調整,從而來適應多種數據集合展現出色的性能。

內省式排序

俗話說俠者講究刀、槍、劍、戟、斧、鉞、鉤、叉等諸多兵器,這也告訴我們一個道理沒有哪種兵器是無敵的,只有在某些場景下的明顯優勢,這跟軟件工程沒有銀彈是一樣的。

回到我們的排序算法上,排序算法也可謂是百花齊放:冒泡排序、選擇排序、插入排序、快速排序、堆排序、桶排序等等。

雖然一批老一輩的排序算法是O(n^2)的,優秀的算法可以到達O(nlogn),但是即使都是nlogn的快速排序和堆排序都有各自的長短之處,插入排序在數據幾乎有序的場景下性能可以到達O(n),有時候我們應該做的不是沖突對比而是融合創新。

內省排序是由David Musser在1997年設計的排序算法。這個排序算法首先從快速排序開始,當遞歸深度超過一定深度(深度為排序元素數量的對數值)后轉為堆排序,David Musser大牛是STL領域響當當的人物。

拋開語境一味地對比孰好孰壞其實都沒有意義,內省式排序就是集大成者,為了能讓排序算法達到一個綜合的優異性能,內省式排序算法結合了快速排序、堆排序、插入排序,并根據當前數據集的特點來選擇使用哪種排序算法,讓每種算法都展示自己的長處,這種思想確實挺啟發人的。

內省排序的排兵布陣

前面提到了內省式排序主要結合了快速排序、堆排序、插入排序,那么不禁要問,這三種排序是怎么排兵布陣的呢?

知己知彼百戰不殆,所以先看下三種排序的優缺點吧!

快速排序

在大量數據時無論是有序還是重復,使用優化后的算法大多可以到達O(nlogn),雖然堆排序也是O(nlogn)但是由于某些原因快速排序會更快一些,當遞歸過深分割嚴重不均勻情況出現時會退化為O(n^2)的復雜度,這時性能會打折扣,這也就是快速排序的短處了。

堆排序

堆排序是快速排序的有力競爭者,最大的特點是可以到達O(nlogn)并且復雜度很穩定,并不會像快速排序一樣可能退化為O(n^2),但是堆排序過程中涉及大量堆化調整,并且元素比較是跳著來的對Cache的局部性特征利用不好,以及一些其他的原因導致堆排序比快速排序更慢一點,但是大O復雜度仍然是一個級別的。

插入排序

插入排序的一個特點是就像我們玩紙牌,在梳理手中的牌時,如果已經比較有序了,那么只需要做非常少的調整即可,因此插入排序在數據量不大且近乎有序的情況下復雜度可以降低到O(n),這一點值得被應用。

優缺點也大致清楚了,所以可以猜想一下內省式排序在實際中是如何調度使這三種排序算法的:

  • 啟動階段 面對大量的待排序元素,首先使用快速排序進行大刀闊斧排序,復雜度可以在O(nlogn)運行
  • 深入階段 在快速排序使用遞歸過程中,涉及棧幀保存切換等諸多遞歸的操作,如果分區切割不當遞歸過深可能造成棧溢出程序終止,因此如果快速排序過程中退化為O(n^2),此時會自動檢測切換為堆排序,因為堆排序沒有惡化情況,都可以穩定在O(nlogn)
  • 收尾階段 在經過快排和堆排的處理之后,數據分片的待排序元素數量小于某個經驗設定值(可以認為是遞歸即將結束的前幾步調用)時,數據其實已經幾乎有序,此時就可以使用插入排序來提高效率,將復雜度進一步降低為O(n)。

寫到這里,筆者又天馬行空地想到了一個場景:

2005年春晚小品中黃宏和鞏漢林出演的《裝修》中黃宏作為裝修工人手拿一大一小兩把錘子,大錘80小錘40,大小錘頭切換使用。

其實跟內省排序切換排序算法是一個道理,所以技術源于生活又高于生活,貼圖一張大家一起體會一下:

用了很多篇幅來講內省思想和內省式排序,相信大家也已經get到了,所以我們具體看下實現細節,這個才是本文的重點,我們繼續往下一起分析吧!

sort算法的實現細節

本文介紹的sort算法是基于SGI STL版本的,并且主要是以侯捷老師的《STL源碼剖析》一書為藍本來進行展開的,因此使用了不帶仿函數的版本,讓我們來一起領略大牛們的杰作吧!圖為筆者買了很久卻一直壓箱底的STL神書:

sort函數的應用場景

SGI STL中的sort的參數是兩個隨機存取迭代器RandomAccessIterator,sort的模板也是基于此種迭代器的,因此如果容器不是隨機存取迭代器,那么可能無法使用通用的sort函數。

  • 關聯容器 map和set底層是基于RB-Tree,本身就已經自帶順序了,因此不需要使用sort算法
  • 序列容器 list是雙向迭代器并不是隨機存取迭代器,vector和deque是隨機存取迭代器適用于sort算法
  • 容器適配器 stack、queue和priority-queue屬于限制元素順序的容器,因此不適用sort算法。

綜上我們可以知道,sort算法可以很好的適用于vector和deque這兩種容器。

sort總體概覽

前面介紹了內省式排序,所以看下sort是怎么一步步來使用introsort的,上一段入口代碼:

  1. template <class RandomAccessIterator> 
  2. inline void sort(RandomAccessIterator first, RandomAccessIterator last) { 
  3.     if (first != last) { 
  4.         __introsort_loop(firstlast, value_type(first), __lg(last - first) * 2); 
  5.         __final_insertion_sort(firstlast); 
  6.     } 

從代碼來看sort使用了first和last兩個隨機存取迭代器,作為待排序序列的開始和終止,進一步調用了__introsort_loop和__final_insertion_sort兩個函數,從字面上看前者是內省排序循環,后者是插入排序。其中注意到__introsort_loop的第三個參數__lg(last - first)*2,憑借我們的經驗來猜(蒙)一下吧,應該遞歸深度的限制,不急看下代碼實現:

  1. template <class Size
  2. inline Size __lg(Size n){ 
  3.     Size k; 
  4.     for(k = 0;n > 1;n >>= 1) ++k; 
  5.     return k; 

這段代碼的意思就是n=last-first,2^k<=n的最大整數k值。

所以整體看當假設last-first=20時,k=4,最大分割深度depth_max=4*2=8,從而我們就可以根據first和last來確定遞歸的最大深度了。

快速排序和堆排序的配合 __introsort_loop函數中主要封裝了快速排序和堆排序,來看看這個函數的實現細節:

  1. //sort函數的入口 
  2. template <class RandomAccessIterator, class T, class Size
  3. void __introsort_loop(RandomAccessIterator first
  4.                       RandomAccessIterator last, T*, 
  5.                       Size depth_limit) { 
  6.     while (last - first > __stl_threshold) { 
  7.         if (depth_limit == 0) { 
  8.             partial_sort(firstlastlast);//使用堆排序 
  9.             return
  10.         } 
  11.         --depth_limit;//減分割余額 
  12.         RandomAccessIterator cut = __unguarded_partition 
  13.           (firstlast, T(__median(*first, *(first + (last - first)/2), 
  14.                                    *(last - 1))));//三點中值法分區過程 
  15.         __introsort_loop(cut, last, value_type(first), depth_limit);//子序列遞歸調用 
  16.         last = cut;//迭代器交換 切換到左序列 
  17.     } 
  18. //基于三點中值法的分區算法 
  19. template <class RandomAccessIterator, class T> 
  20. RandomAccessIterator __unguarded_partition(RandomAccessIterator first,  
  21.                                            RandomAccessIterator last,  
  22.                                            T pivot) { 
  23. while (true) { 
  24.     while (*first < pivot) ++first
  25.     --last; 
  26.     while (pivot < *last--last; 
  27.     if (!(first < last)) return first
  28.     iter_swap(firstlast); 
  29.     ++first

各位先不要暈更不要蒙圈,一點點分析肯定可以拿下的。

  • 先看參數兩個隨機存取迭代器first和last,第三個參數是__lg計算得到的分割深度;
  • 這時候我們進入了while判斷了last-first的區間大小,__stl_threshold為16,侯捷大大特別指出__stl_threshold的大小可以是5~20,具體大小可以自己設置,如果大于__stl_threshold那就才會繼續執行,否則跳出;假如現在區間大小大于__stl_threshold,判斷第三個參數depth_limit是否為0,也就是是否出現了分割過深的情況,相當于給了一個初始最大值,然后每分割一次就減1,直到depth_limit=0,這時候調用partial_sort,從《stl源碼剖析》的其他章節可以知道,partial_sort就是對堆排序的封裝,看到這里有點意思了主角之一的heapsort出現了;
  • 繼續往下看,depth_limit>0 尚有分割余額,那就燥起來吧!這樣來到了__unguarded_partition,這個函數從字眼看是快速排序的partiton過程,返回了cut隨機存取迭代器,__unguarded_partition的第三個參數__median使用的是三點中值法來獲取的基準值Pivot,至此快速排序的partition的三個元素集齊了,最后返回新的切割點位置;
  • 繼續看馬上搞定啦,__introsort_loop出現了,果然遞歸了,特別注意一下這里只有一個遞歸,并且傳入的是cut和last,相當于右子序列,那左子序列怎么辦啊?別急往下看,last=cut峰回路轉cut變成了左子序列的右邊界,這樣就開始了左子序列的處理;

快速排序的實現對比

前面提到了在sort中快速排序的寫法和我們之前見到的有一些區別,看了一下《STL源碼剖析》對快排左序列的處理,侯捷老師是這么寫的:"寫法可讀性較差,效率并沒有比較好",看到這里更蒙圈了,不過也試著分析一下吧!

圖為:STL源碼剖析中侯捷老師對該種寫法的注釋

常見寫法:

  1. //快速排序的常見寫法偽代碼 
  2. quicksort(arr,left,right){ 
  3.     pivoit = func(arr);//使用某種方法獲取基準值 
  4.     cut = partition(left,right,pivot);//左右邊界和基準值來共同確定分割點位置 
  5.     quicksort(arr,left,cut-1);//遞歸處理左序列 
  6.     quicksort(arr,cut+1,right);//遞歸處理右序列 

SGI STL中的寫法:

  1. stl_quicksort(first,last){ 
  2.       //循環作為外層控制結構 
  3.       while(ok){ 
  4.          cut = stl_partition(first,last,_median(first,last));//分割分區 
  5.          stl_quicksort(cut,last);//遞歸調用 處理右子序列 
  6.          last = cut;//cut賦值為last 相當于切換到左子序列 再繼續循環 
  7.    } 

網上有一些大佬的文章說sgi stl中快排的寫法左序列的調用借助了while循環節省了一半的遞歸調用,是典型的尾遞歸優化思路。

這里我暫時還沒有寫測試代碼做對比,先占坑后續寫個對比試驗,再來評論吧,不過這種sgi的這種寫法可以看看哈。

堆排序的細節

  1. //注:這個是帶自定義比較函數的堆排序版本 
  2. //堆化和堆頂操作 
  3. template <class RandomAccessIterator, class T, class Compare> 
  4. void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, 
  5.                     RandomAccessIterator last, T*, Compare comp) { 
  6.     make_heap(first, middle, comp); 
  7.     for (RandomAccessIterator i = middle; i < last; ++i) 
  8.         if (comp(*i, *first)) 
  9.             __pop_heap(first, middle, i, T(*i), comp, distance_type(first)); 
  10.     sort_heap(first, middle, comp); 
  11. //堆排序的入口 
  12. template <class RandomAccessIterator, class Compare> 
  13. inline void partial_sort(RandomAccessIterator first
  14.                          RandomAccessIterator middle, 
  15.                          RandomAccessIterator last, Compare comp) { 
  16.     __partial_sort(first, middle, last, value_type(first), comp); 

插入排序上場了

__introsort_loop達到__stl_threshold閾值之后,可以認為數據集近乎有序了,此時就可以通過插入排序來進一步提高排序速度了,這樣也避免了遞歸帶來的系統消耗,看下__final_insertion_sort的具體實現:

  1. template <class RandomAccessIterator> 
  2. void __final_insertion_sort(RandomAccessIterator first,  
  3.                             RandomAccessIterator last) { 
  4.     if (last - first > __stl_threshold) { 
  5.         __insertion_sort(firstfirst + __stl_threshold); 
  6.         __unguarded_insertion_sort(first + __stl_threshold, last); 
  7.     } 
  8.     else 
  9.         __insertion_sort(firstlast); 

來分析一下__final_insertion_sort的實現細節吧:

  • 引入參數隨機存取迭代器first和last
  • 如果last-first > __stl_threshold不成立就調用__insertion_sort,這個相當于元素數比較少了可以直接調用,不用做特殊處理;
  • 如果last-first > __stl_threshold成立就進一步再分割成兩部分,分別調用__insertion_sort和__unguarded_insertion_sort,兩部分的分割點是__stl_threshold,不免要問這倆函數有啥區別呀?

__insertion_sort的實現

  1. //逆序對的調整 
  2. template <class RandomAccessIterator, class T> 
  3. void __unguarded_linear_insert(RandomAccessIterator last, T value) { 
  4.     RandomAccessIterator next = last
  5.     --next; 
  6.     while (value < *next) { 
  7.         *last = *next
  8.         last = next
  9.         --next; 
  10.     } 
  11.     *last = value; 
  12.  
  13. template <class RandomAccessIterator, class T> 
  14. inline void __linear_insert(RandomAccessIterator first,  
  15.                             RandomAccessIterator last, T*) { 
  16.     T value = *last
  17.     if (value < *first) { 
  18.         copy_backward(firstlastlast + 1);//區間移動 
  19.         *first = value; 
  20.     } 
  21.     else 
  22.         __unguarded_linear_insert(last, value); 
  23.  
  24. //__insertion_sort入口 
  25. template <class RandomAccessIterator> 
  26. void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { 
  27.     if (first == lastreturn;  
  28.     for (RandomAccessIterator i = first + 1; i != last; ++i) 
  29.         __linear_insert(first, i, value_type(first)); 

在插入函數中同樣出現了__unguarded_xxx這種形式的函數,unguarded單詞的意思是無防備的,無保護的,侯捷大大提到這種函數形式是特定條件下免去邊界檢驗條件也能正確運行的函數。

copy_backward也是一種整體移動的優化,避免了one by one的調整移動,底層調用memmove來高效實現。

__unguarded_insertion_sort的實現

  1. template <class RandomAccessIterator, class T> 
  2. void __unguarded_insertion_sort_aux(RandomAccessIterator first,  
  3.                                     RandomAccessIterator last, T*) { 
  4.     for (RandomAccessIterator i = first; i != last; ++i) 
  5.         __unguarded_linear_insert(i, T(*i)); 
  6.  
  7. template <class RandomAccessIterator> 
  8. inline void __unguarded_insertion_sort(RandomAccessIterator first,  
  9.                                 RandomAccessIterator last) { 
  10.     __unguarded_insertion_sort_aux(firstlast, value_type(first)); 

關于插入排序的這兩個函數的實現和目的用途,展開起來會很細致,所以后面想著單獨在寫插入排序時單獨拿出了詳細學習一下,所以本文就暫時先不深究了,感興趣的讀者可以先行閱讀相關資料,后續我們再共同辯駁哈!

總結

本文主要闡述了內省式排序的思想和基本實現思路,并且以此為切入點對sgi stl中sort算法的實現來進行了一些解讀。

stl的作者們為了追求極致性能所以使用了大量的技巧,對此本文并沒有過多展開,也主要是段位不太高怕解讀錯了,聰明的讀者們可以嘗試來剖析一探大牛們的巔峰技藝。

 

責任編輯:武曉燕 來源: 后端研究所
相關推薦

2011-11-07 09:26:51

域樹

2009-11-11 15:29:15

ADO初始化

2010-03-17 17:11:04

Java線程通信

2021-10-14 08:58:48

Java冒泡排序

2024-12-10 00:00:10

MySQLJOIN算法

2022-01-10 08:31:29

React組件前端

2013-07-08 09:30:32

排序算法

2022-03-07 09:42:21

Go快速排序

2012-09-10 09:37:41

2015-07-16 09:15:23

面試程序員武俠

2021-03-02 13:53:37

人工智能深度學習Google mBER

2019-04-28 16:10:50

設計Redux前端

2021-12-09 08:31:01

ReentrantLoAQS

2022-12-26 00:00:00

排序算法洗牌算法算法

2025-02-27 00:32:35

2011-07-13 14:28:09

STL算法

2015-05-05 11:04:31

CoreOS自動化運維

2015-10-12 10:07:36

數據藝術市場

2010-07-09 10:13:42

UDP協議
點贊
收藏

51CTO技術棧公眾號

亚洲精品永久视频| 成人黄色影片在线| 一本加勒比北条麻妃| 主播大秀视频在线观看一区二区| 成人动漫av在线| 国产成人av网址| 无码人妻精品一区二区三区夜夜嗨| 97品白浆高清久久久久久| 日韩欧美极品在线观看| 自拍偷拍一区二区三区| 深爱五月激情五月| 久久精品国产**网站演员| 久久久久久久激情视频| 国产在线综合视频| av不卡一区二区| 欧美日韩极品在线观看一区| www.av蜜桃| 69av在线| 91美女福利视频| 91亚洲精华国产精华| 日韩不卡视频在线| 欧美一区精品| 伊人久久久久久久久久久| 亚洲成人福利视频| 欧美一级网址| 91国产视频在线观看| 女人帮男人橹视频播放| 免费av网站在线观看| 久久久久久久久久久黄色| 91视频99| 国产巨乳在线观看| 麻豆精品新av中文字幕| 18性欧美xxxⅹ性满足| 久草综合在线视频| 999精品视频| 尤物九九久久国产精品的分类| 国产性生活毛片| 欧州一区二区三区| 欧美人狂配大交3d怪物一区| 能看的毛片网站| 日韩激情电影| 午夜精品久久久久久久99樱桃 | 国产精品国产一区二区三区四区| 日韩午夜高潮| 欧美日本精品在线| 成人免费黄色小视频| 91日韩视频| 日韩中文字幕久久| 亚洲女人毛茸茸高潮| 国产日产精品一区二区三区四区的观看方式 | 波多野结衣中文字幕一区| 亚洲精品欧美一区二区三区| 一二三区中文字幕| 国内一区二区视频| 91视频8mav| 国产乱子伦精品无码码专区| 九色综合国产一区二区三区| 成人免费网站在线| 国产精品无码久久久久成人app| 欧美aⅴ一区二区三区视频| 国产精品福利无圣光在线一区| 精品国产一区二区三区四| 麻豆亚洲精品| 国产精品高清在线| 中文字幕乱码无码人妻系列蜜桃| 日韩福利视频导航| 国产精品一区=区| 91久久精品国产91性色69| 蜜桃视频在线一区| 成人国产精品一区二区| 国产熟女一区二区三区四区| 国产成人在线视频网站| 国产伦精品一区二区三区高清版 | 国产精品小仙女| 国产九色91| 可以在线观看的av| 中文字幕av不卡| 在线观看av的网址| а√天堂中文资源在线bt| 黑人狂躁日本妞一区二区三区| 凹凸日日摸日日碰夜夜爽1| 粉嫩一区二区三区| 91精品在线免费| 国产在线不卡av| 国产真实有声精品录音| 精品国产自在精品国产浪潮| 欧美国产日韩综合| 亚洲免费网站| 91免费观看网站| 日韩中文字幕影院| 国产日韩欧美精品在线| 一级全黄肉体裸体全过程| a国产在线视频| 欧美伊人久久久久久久久影院| 亚洲天堂国产视频| 欧美电影免费网站| 中文字幕自拍vr一区二区三区| 91porn在线视频| 销魂美女一区二区三区视频在线| 国产一区二中文字幕在线看| 狠狠人妻久久久久久综合麻豆| 久久综合成人精品亚洲另类欧美| 一区二区三区四区视频在线| 9999在线视频| 欧美绝品在线观看成人午夜影视| 秘密基地免费观看完整版中文| 国产午夜一区| 欧美精品videofree1080p| 波多野结衣电车| 俄罗斯黄色录像| 日日夜夜综合| 亚洲韩国欧洲国产日产av | 亚洲中文字幕在线观看| 国产福利不卡视频| 一区二区三区四区国产| 亚洲v.com| 欧美一区二区三区免费| 日韩中文字幕有码| 激情欧美日韩| 91精品视频免费观看| 久草视频在线看| 亚洲综合精品久久| www.桃色.com| 国产亚洲欧美日韩在线观看一区二区| 欧美激情手机在线视频| 在线视频 中文字幕| 久久先锋影音av鲁色资源网| 日本一级黄视频| 亚洲欧洲二区| 日韩中文字幕免费| 无码人妻精品一区二区50| www.欧美精品一二区| 亚洲爆乳无码精品aaa片蜜桃| 99re久久| 亚洲香蕉伊综合在人在线视看| 久久国产精品波多野结衣av| 国模大尺度一区二区三区| 日韩精品在在线一区二区中文 | 国产精品久久久久久久av大片| 欧美熟妇交换久久久久久分类 | 国产精品一区二区男女羞羞无遮挡 | 高清日韩中文字幕| 欧美国产日韩xxxxx| 97在线视频人妻无码| 国产精品久久午夜| 爆乳熟妇一区二区三区霸乳| 亚洲天堂日韩在线| 欧美一区二区三区……| 四虎在线免费看| 亚洲超碰97人人做人人爱| 精品人妻人人做人人爽夜夜爽| 99精品综合| 成人淫片在线看| 精品欧美色视频网站在线观看| 在线播放一区二区三区| 国产黄a三级三级| 精品影视av免费| a级黄色片网站| 精品国产亚洲一区二区三区大结局| 日韩在线观看你懂的| 国产强伦人妻毛片| 亚洲一区视频在线观看视频| 一级黄色片毛片| 国产亚洲精品v| 欧美主播一区二区三区美女 久久精品人 | 精品欧美一区免费观看α√| 亚洲精品国产动漫| 国产不卡一区二区在线播放| 搞黄视频免费在线观看| 欧美日韩三级视频| 国产精品三区在线观看| 国产成人在线视频播放| 精品这里只有精品| 国产探花在线精品一区二区| 国产综合久久久久久| 97caopor国产在线视频| 亚洲第一在线视频| 日批视频免费在线观看| 国产精品亲子伦对白| 无码人妻少妇色欲av一区二区| 亚洲精品男同| 视频在线99| 久久久精品区| 97超级碰在线看视频免费在线看| 国产在线91| 欧美一级日韩一级| 精品欧美一区二区三区免费观看| 欧美经典一区二区| 在线观看你懂的视频| 香蕉久久国产| 在线观看污视频| 九九免费精品视频在线观看| 国产主播在线一区| 五月天av在线| 久久天天躁日日躁| 欧美在线一卡| 日韩一级黄色片| 无码无套少妇毛多18pxxxx| 亚洲人一二三区| 在线不卡av电影| 国产综合一区二区| 青青青在线播放| 自拍视频亚洲| 亚洲成人18| 欧美丝袜美腿| 114国产精品久久免费观看| 中文在线资源| 欧美黑人极品猛少妇色xxxxx| 国产九色在线| 亚洲国产古装精品网站| 91丨porny丨在线中文| 欧美日韩中文字幕在线视频| 特级片在线观看| 中文字幕不卡在线| 成人免费毛片日本片视频| 国内精品伊人久久久久影院对白| 乱子伦视频在线看| 亚洲青涩在线| 日韩精品手机在线观看| 精品国产午夜| 裸模一区二区三区免费| 97久久综合精品久久久综合| 成人欧美一区二区三区在线| 成人软件在线观看| 69久久夜色精品国产69| 日本天码aⅴ片在线电影网站| 日韩亚洲综合在线| 大片免费播放在线视频| 亚洲美女av网站| 人妻一区二区三区四区| 精品伦理精品一区| 精品久久在线观看| 欧美一区二区三区视频在线| 亚洲影院一区二区三区| 欧美性大战xxxxx久久久| 亚洲黄色激情视频| 婷婷国产v国产偷v亚洲高清| 国产午夜久久久| 亚洲精品视频在线观看免费| 色哟哟一一国产精品| 国产精品美女久久久久久| 免费看91的网站| 中文字幕国产一区二区| 人妻熟人中文字幕一区二区| 久久久久久99精品| 精品欧美一区二区久久久| 久久嫩草精品久久久精品一| 人妻丰满熟妇aⅴ无码| 99视频一区二区| 91黄色免费视频| 91论坛在线播放| 无码h肉动漫在线观看| wwwwxxxxx欧美| 久久亚洲AV成人无码国产野外| 91免费看片在线观看| 丝袜美腿中文字幕| 国产亚洲精品精华液| 调教驯服丰满美艳麻麻在线视频| 国产欧美日本一区视频| 美女福利视频网| 亚洲免费观看高清在线观看| 久久久久久久蜜桃| 亚洲18女电影在线观看| 你懂的国产在线| 日本久久一区二区三区| 一级黄色片免费看| 日韩欧美国产三级电影视频| 神马久久久久久久久久| 亚洲免费av电影| 在线播放日本| 欧美另类在线播放| 极品在线视频| 国产精品久久久久av| 亚洲男人在线| 国产精品毛片va一区二区三区| 午夜先锋成人动漫在线| 天堂一区二区三区 | 亚洲va在线观看| 欧美三级电影在线观看| 国内精品偷拍视频| 国产手机视频精品| 久草免费在线| 6080yy精品一区二区三区| 中文字幕日本一区二区| 亚洲影院污污.| 亚洲国产欧美日韩在线观看第一区| 午夜精品短视频| 国内精品久久久久久久影视蜜臀 | 精品一区二区三区av| 在线观看欧美一区二区| 久久久九九九九| 欧美色图亚洲天堂| 色丁香久综合在线久综合在线观看| 国产精品福利电影| 亚洲欧美在线x视频| www久久日com| 国产成人综合亚洲| 99这里只有精品视频| 日韩久久不卡| 日韩一区二区免费看| 亚洲国产高清av| 北条麻妃国产九九精品视频| 国产馆在线观看| 欧美日韩精品二区| 99精品免费观看| 这里只有精品丝袜| 日韩伦理在线| aa成人免费视频| 日韩欧美综合| 久久无码高潮喷水| 国产a精品视频| 日韩精品一区二区三区在线视频| 狠狠躁夜夜躁人人爽超碰91| 国产成人精品白浆久久69| 亚洲系列中文字幕| 麻豆mv在线看| 电影午夜精品一区二区三区| 国产高清一区二区| 亚洲一二三区av| 91丨porny丨中文| 九九视频免费看| 欧美精品v日韩精品v韩国精品v| 免费在线黄色电影| 午夜伦理精品一区| 亚洲成av人片在线观看www| 亚洲国产精品视频一区| 亚洲永久字幕| 人妻激情偷乱频一区二区三区| 亚洲图片激情小说| 中文字幕在线观看高清| 亚洲欧洲xxxx| 亚洲一二三四| 久久av一区二区三区亚洲| 欧美午夜电影在线观看 | 9色porny| 国产xxx精品视频大全| 91视频最新网址| 欧美日韩午夜影院| avtt亚洲| 国产精品亚洲一区二区三区| 国产欧美日韩在线观看视频| 欧美性大战久久久久xxx| 91在线丨porny丨国产| 国产主播在线观看| 亚洲国产精品字幕| 永久免费毛片在线播放| 久久久99爱| 国产亚洲午夜| 一级片视频免费看| 91精品福利在线| 在线观看完整版免费| 国产免费一区二区三区在线能观看| 大色综合视频网站在线播放| 国产91色在线观看| 最近中文字幕一区二区三区| 99久久精品国产成人一区二区| 欧美另类极品videosbest最新版本 | 91青青在线视频| 国产又爽又黄的激情精品视频 | 国产深夜男女无套内射| 99re在线视频这里只有精品| 久久久久99精品成人片我成大片| 亚洲区在线播放| 成人一级视频| 国产精品12p| 不卡一区二区在线| 精品不卡一区二区| 色噜噜久久综合伊人一本| av日韩一区| 欧美黄色免费网址| 久久综合九色综合欧美亚洲| 真实的国产乱xxxx在线91| 中文字幕久热精品在线视频| 欧美日韩黄网站| 蜜桃传媒一区二区三区| 欧美韩日一区二区三区| 国产视频在线观看免费| 91精品国产乱码久久久久久蜜臀 | 中文字幕av导航| 成人精品亚洲人成在线| 伦av综合一区| 日韩中文字幕精品| 红杏成人性视频免费看| 亚洲成色www.777999| 亚洲精品乱码久久久久久| 日韩av成人| 91人人爽人人爽人人精88v| 亚洲黑丝一区二区| 国产成人在线网址| 精品成人私密视频| 国产69精品久久| 成年人网站国产| 国产日韩成人精品| 好吊色一区二区三区| 国产精品久久久久久久久久新婚| 国产一区日韩一区| 91成人精品一区二区| 亚洲福利在线观看| 亚洲资源在线| 久久9精品区-无套内射无码|