精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美日本在线播放| 26uuuu精品一区二区| 日韩在线观看成人| aaaaa黄色片| 大黄网站在线观看| ww久久中文字幕| 国产一区红桃视频| 中文字幕一区二区三区手机版| 妖精视频一区二区三区| 欧美人伦禁忌dvd放荡欲情| 国产欧美日韩小视频| 欧美女子与性| 国产精品资源在线观看| 日本一欧美一欧美一亚洲视频| 久久久国产一级片| 久9re热视频这里只有精品| 精品污污网站免费看| 亚洲理论电影在线观看| 最新av网站在线观看 | 亚洲欧美激情一区二区三区| jizz内谢中国亚洲jizz| 亚洲黄色免费电影| 亚洲不卡1区| www久久久久久| 久久综合影音| 91精品国产99| 麻豆chinese极品少妇| 色777狠狠狠综合伊人| 亚洲黄页视频免费观看| 久久久精品视频国产| 日本精品在线一区| 精品久久中文字幕| 一级性生活视频| 午夜不卡视频| 日本一区免费视频| 日本电影一区二区三区| 国产成人三级在线观看视频| 精品中文av资源站在线观看| 国产精品久久久久久久久久久新郎 | 日本中文字幕一级片| 在线观看美女网站大全免费| 91丨porny丨蝌蚪视频| 国产成人免费电影| 99精品国产99久久久久久97| 久久国产夜色精品鲁鲁99| 日本亚洲欧洲色| 天堂а√在线中文在线新版| 日韩天天综合| 国内精久久久久久久久久人| 免费看一级一片| 中国成人一区| 久久综合伊人77777蜜臀| 免费成人深夜蜜桃视频| 青青草97国产精品麻豆| 中文字幕在线看视频国产欧美在线看完整| 黄色a一级视频| 欧美日韩一区二区三区在线电影 | 成人爽a毛片一区二区| 国产精品正在播放| 成人xxxxx色| 亚洲精品一级片| 成人午夜大片免费观看| 国产精品视频福利| 五月婷婷在线播放| 久久综合视频网| 欧美一区1区三区3区公司 | 久久久久久久久久久免费精品| 日韩一级片av| 在线观看一区| 26uuu久久噜噜噜噜| 男人天堂2024| 日韩电影在线免费看| 国产精品自产拍在线观| 国产成人麻豆精品午夜在线| 国产成人av电影在线播放| 国产日韩欧美一区二区三区四区 | 亚洲精品成人一区| 日韩一区二区在线看片| 精品视频站长推荐| 国产亚洲欧美日韩在线观看一区二区 | 青青草视频播放| 国产99亚洲| 久久精品国产2020观看福利| 免看一级a毛片一片成人不卡| 亚洲国产午夜| 国产精品久久精品| 亚洲h视频在线观看| 久久综合九色综合久久久精品综合 | 精品人妻无码一区二区色欲产成人| 国产999精品久久| 蜜桃网站成人| 久操视频在线播放| 亚洲va天堂va国产va久| 亚洲五月天综合| 精品久久亚洲| 亚洲免费视频观看| 顶臀精品视频www| 一区二区国产精品| 国产综合久久久久久| 免费观看国产精品| 国产精品三级av在线播放| 人妻无码一区二区三区四区| www.日韩| 日韩欧美国产电影| av手机在线播放| 国产精品观看| 国产精品久久久久久亚洲影视| 国产黄色免费大片| 国产欧美视频一区二区| 黄色激情在线视频| 欧美日韩免费电影| 亚洲精品在线91| 私库av在线播放| 日韩av二区在线播放| 国产精品综合久久久久久| 日韩三级影院| 色狠狠一区二区三区香蕉| 欧美一级片在线免费观看| 欧美色图一区| 浅井舞香一区二区| 成人久久精品人妻一区二区三区| 国产精品色婷婷| 国产成人综合一区| 久久久久观看| 另类亚洲自拍| 男插女视频网站| 二吊插入一穴一区二区| 欧美性欧美巨大黑白大战| 中文字幕1区2区| 欧美国产小视频| 欧美激情极品视频| 97人妻一区二区精品免费视频| 波多野结衣一区二区三区| 国产一区一区三区| 日韩av懂色| 国产亚洲精品成人av久久ww| 欧美三级韩国三级日本三斤在线观看| 国产一区在线不卡| 偷拍盗摄高潮叫床对白清晰| 精品国模一区二区三区| 精品一区电影国产| 成年人午夜视频| 成人免费毛片a| 91成人综合网| 精品国产亚洲一区二区三区| 久久激情视频免费观看| 亚洲系列在线观看| 国产精品久久久久久久久久久免费看| 天堂中文视频在线| 狠狠做六月爱婷婷综合aⅴ| 欧美一区亚洲一区| 人人九九精品| 色综合久久综合| 国产又粗又猛又爽视频| 老**午夜毛片一区二区三区| 日韩高清av| 78精品国产综合久久香蕉| 亚洲桃花岛网站| 这里只有精品999| 国产精品卡一卡二卡三| 中文字幕网av| 国产精品久久观看| 91亚洲va在线va天堂va国 | 川上优的av在线一区二区| 日韩欧美国产中文字幕| 亚洲一区视频在线播放| 美国一区二区三区在线播放| 一区二区成人国产精品 | 91成人在线观看喷潮| 新91视频在线观看| 麻豆成人久久精品二区三区红| 亚洲欧洲精品一区二区| 高清一区二区中文字幕| 久久99国产综合精品女同| 欧洲av在线播放| 欧美性猛交xxxx乱大交3| 日韩免费成人av| 国产一区二三区| 妺妺窝人体色777777| 欧美人与拘性视交免费看| 国产精品美女久久久免费| 国产美女在线观看| 亚洲精品国精品久久99热一| 69视频免费看| 亚洲精品伦理在线| 一级做a爰片毛片| 蜜桃久久久久久| 国产成人永久免费视频| 蜜桃一区二区| 96久久精品| 成人一区福利| 成人97在线观看视频| 神马久久高清| 制服丝袜亚洲精品中文字幕| 91成人福利视频| 99re这里只有精品6| 在线观看国产一级片| 亚洲国产国产亚洲一二三| 午夜一区二区三区| 伊人久久影院| 国产精品爽爽爽| www.色在线| 久久久精品欧美| 日本一区二区三区在线观看视频| 538在线一区二区精品国产| 久久久久久久福利| 国产精品全国免费观看高清| 中文字幕a在线观看| 四虎国产精品成人免费入口| 国产凹凸在线观看一区二区| 久久撸在线视频| 国产精品试看| 日本免费成人网| 99国产**精品****| 日韩欧美电影一区二区| 精品国产导航| 99国产在线| 91精品国产色综合久久不卡粉嫩| 人人澡人人澡人人看欧美| 黑人玩欧美人三根一起进| 色妞一区二区三区| 国产三级电影在线观看| 亚洲精品97久久| 国产黄色免费大片| 51久久夜色精品国产麻豆| 国语对白做受69按摩| 欧美午夜视频在线观看| 伊人国产在线观看| 亚洲精品一卡二卡| 精品国产国产综合精品| 国产欧美精品一区二区三区四区| www.88av| 97久久超碰国产精品| www日本在线观看| 国内一区二区在线| 亚洲综合婷婷久久| 久久99久久久久| 国产一二三区av| 青青国产91久久久久久| 精品视频一区二区在线| 国产精品日韩| av免费中文字幕| 丝袜亚洲精品中文字幕一区| 精品99在线视频| 噜噜噜在线观看免费视频日韩 | 捆绑变态av一区二区三区| 青青在线视频免费| 日韩精品三区四区| 自拍偷拍 国产| 免费在线成人网| 中文字幕网av| 国产揄拍国内精品对白| 亚洲理论中文字幕| 国产激情一区二区三区桃花岛亚洲| 亚洲涩涩在线观看| 国产一区欧美日韩| 免费看的av网站| 成人av免费在线| 99re久久精品国产| 久久精品亚洲一区二区三区浴池| 右手影院亚洲欧美| 国产日韩欧美精品一区| 日日操免费视频| 亚洲天天做日日做天天谢日日欢 | 一区二区三区色| 玖玖爱免费视频| 精品国产乱码久久久久久天美| 在线视频一区二区三区四区| 欧美性生活影院| 99热这里只有精品66| 欧美精品一区二区三区蜜臀 | www.欧美精品| 男女视频在线| 国产成人91久久精品| 日韩免费大片| 99在线高清视频在线播放| 蜜桃久久久久| 五码日韩精品一区二区三区视频| 五月婷婷六月综合| 欧美日韩精品在线一区二区| 三级欧美韩日大片在线看| 在线观看av免费观看| 成人高清伦理免费影院在线观看| 国产精品一二三区在线观看| 1000部国产精品成人观看| 日本熟妇一区二区| 欧美无乱码久久久免费午夜一区| 国产草草影院ccyycom| 亚洲精品视频网上网址在线观看| 日本最新在线视频| 91国内免费在线视频| 欧美伊人亚洲伊人色综合动图| 国产精品久久久对白| 精品视频亚洲| 成人午夜视频在线观看免费| 毛片不卡一区二区| 国产亚洲色婷婷久久99精品91| 国产精品免费网站在线观看| 国产午夜精品无码| 欧美日韩国产综合视频在线观看| 日本国产在线观看| xvideos亚洲| 第84页国产精品| av成人免费观看| 色综合咪咪久久网| 国产xxxxx在线观看| 国产一区二区三区免费看| 中文字幕在线1| 亚洲成av人片在线观看| 91精品国产乱码久久久久| 亚洲另类激情图| 高清电影在线观看免费| 成人xxxxx| 精品视频久久| 免费日韩视频在线观看| 成人免费的视频| 男人与禽猛交狂配| 欧美色老头old∨ideo| 色视频在线看| 亚州av一区二区| 亚洲不卡在线| 肉大捧一出免费观看网站在线播放| 免费在线观看一区二区三区| 三上悠亚ssⅰn939无码播放| 亚洲一本大道在线| 国产chinasex对白videos麻豆| 色偷偷综合社区| 欧洲成人一区| 欧美一区国产一区| 亚洲综合国产| 亚洲久久久久久| 性感美女极品91精品| www.国产欧美| 欧美寡妇偷汉性猛交| 4438五月综合| 自拍偷拍99| 精品在线视频一区| 中文字幕精品亚洲| 欧美手机在线视频| 最新97超碰在线| 国产精品日日摸夜夜添夜夜av| 国产一区二区三区91| 凹凸国产熟女精品视频| heyzo一本久久综合| 日韩精品一区二区三区国语自制| 精品国产sm最大网站| 视频在线这里都是精品| 99久久精品免费看国产一区二区三区 | 在线亚洲观看| 极品粉嫩小仙女高潮喷水久久| 精品欧美aⅴ在线网站| 日本私人网站在线观看| 欧美在线视频网站| 精品久久久中文字幕| 一本岛在线视频| 亚洲色图欧美偷拍| 亚洲第九十九页| 午夜精品久久久久久久99热浪潮| 老司机aⅴ在线精品导航| 免费黄色福利视频| 国产午夜亚洲精品理论片色戒| 日韩成人中文字幕| 黑人巨大精品欧美一区二区桃花岛| 茄子视频成人在线观看| 蜜臀av国产精品久久久久| 亚洲怡红院在线观看| 日韩欧美国产综合一区| 九色porny丨首页入口在线| 欧美1o一11sex性hdhd| 免费人成精品欧美精品| 国产黄色小视频网站| 精品国产1区二区| 唐人社导航福利精品| 亚洲午夜精品久久久久久浪潮| 国产在线精品视频| 日本三级2019| 国产亚洲精品久久久久动| 在线免费观看亚洲| 男女私大尺度视频| 欧美国产精品v| 午夜精品久久久久久久96蜜桃| 97热精品视频官网| 色乱码一区二区三区网站| 国产调教打屁股xxxx网站| 日韩欧美精品网站| 国产午夜精品久久久久免费视| 国产视频一区二区三区四区| 日韩av网站在线观看| 免费在线视频观看| 国产一区二区三区精品久久久 | 久久精品国产精品青草| 精品少妇theporn| 在线观看国产精品淫| 澳门成人av| 久久影院视频免费| 国产成人免费看一级大黄| 国产国语videosex另类| 欧美日韩三级| 2017亚洲天堂| 亚洲精品在线看|