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

100行C代碼終端打印樹形結構

開發(fā) 后端
這是一篇講究套路的數(shù)據(jù)結構實戰(zhàn)教學文,閱讀需要約20分鐘。

講究套路之前,先來回答三個問題。

為什么要打印樹形結構

樹形結構是算法里很常見的一種數(shù)據(jù)結構,從二叉樹到多叉樹,還有很多變種。很多涉及到算法的工作,就需要程序員自己手動實現(xiàn)樹形結構,但出于結構本身復雜性,不太容易做對,需要一種調試工具來檢測正確性。一般的調試手段無非就是加打印,GDB上斷點,寫測試用例等,但這些局部以及外部的調試信息對于數(shù)據(jù)結構的整體把握提供的幫助十分有限,經(jīng)驗不足的程序員甚至可能會迷失在一大片調試信息的汪洋大海中找不著北。理解算法本身是一回事,自己動手是另一回事了,這跟我們理解算法的思維方式有關——對于數(shù)據(jù)結構而言,我們的感知是形象化的,比方腦海中自動出現(xiàn)一幅圖,動態(tài)的插入刪除,每個節(jié)點是如何變動的,平衡的時候局部是怎么旋轉的等等,對智力正常的人來說不是什么難事。但對機器來說,它要面對的是只是一堆基于狀態(tài)的指令而已,將人的形象思維轉化為狀態(tài)機,本身是一件艱難的工作,因為我們很難感知并存儲這么多狀態(tài),這就需要工具來輔助,最好是畫出整個形狀結構,以直觀地提醒我們哪里出錯了,所謂“觀其形,見其義”

我們知道Linux有個tree命令用來打印樹狀目錄列表,可以將某個目錄下的所有文件和子目錄一覽無遺,非常直觀,本文可以說就是為了實現(xiàn)這個效果,并給出源碼實現(xiàn)。

為什么用深度優(yōu)先遍歷

主要是方便輸出。在終端輸出一般都是從左至右,從上到下,對于樹形結構來說,前者自然表達的是從根節(jié)點到葉子節(jié)點,后者自然表達的是相鄰分支,深度優(yōu)先遍歷符合輸出次序。

實際上廣度優(yōu)先遍歷實現(xiàn)起來更簡單,只要在每一層左端建立一個鏈表頭,將同一層的節(jié)點橫向串聯(lián)起來,從上到下遍歷鏈表頭數(shù)組就可以了。但考慮以下幾點:

  • 我們的屏幕沒有這么寬,足以容納整棵樹,而且我們更趨向于縱向滾動瀏覽;
  • 層次關系很難表示,光實現(xiàn)對齊就很麻煩;
  • 每個節(jié)點需要維護一個額外next指針,如果這不是數(shù)據(jù)結構本身所需要的成員,對于存儲空間來說是個額外的負擔。

這也說明深度優(yōu)先遍歷第二個優(yōu)點,它的實現(xiàn)對于數(shù)據(jù)結構本身是非侵入式的。

為什么使用非遞歸遍歷

其實這是一個見仁見智的問題。遞歸還是非遞歸,不過是兩種不同的遍歷形式,不存在絕對的優(yōu)劣,而且一般情況下可以相互補充。我個人選擇非遞歸出于以下幾種因素:

  • 避免樹層次過多導致函數(shù)調用堆棧溢出;
  • 避免C語言函數(shù)調用開銷;
  • 所有狀態(tài)可見可控。

當然以上因素并不重要,開心就好。

一切皆套路,不變應萬變

既然本文講究套路,那么干脆現(xiàn)在就把套路給出來好了,偽代碼形式:

/* log對象 */ typedef struct node_backlog {     node指針;     回溯點位置(索引); };  /* Dump */ void dump(tree) {     從根節(jié)點開始迭代;     初始化log堆棧;     for (; ;) {         if (節(jié)點指針為空) {             從log對象中獲取回溯點位置;             if (不存在,或無效的回溯點) {                 壓棧空節(jié)點指針;             } else {                 壓棧當前節(jié)點指針,同時記錄下一個回溯點位置;             }             if (回溯點位置索引為0) {                 輸出層次縮進、畫路徑,打印節(jié)點內容;             }             進入下一層;         } else {             if (log堆棧為空) return;             彈出log對象,獲取最近記錄的節(jié)點指針;         }     } } 

簡單吧?而且我敢說,這個套路對于所有樹形結構都是通用的,只要能夠深度遍歷。

不信我給出三個實戰(zhàn)例子。

目錄樹或字典樹

代碼在gist。這是個MIB樹,是管理網(wǎng)絡節(jié)點(設備)用的。簡要地講,它具有兩重特性:

  • 節(jié)點之間的層次嵌套關系,決定了它屬于目錄層次結構;
  • 節(jié)點的key具有公共前綴,使得它也類似于(或可用于)字典結構。

我們不需要關心其CRUD實現(xiàn),只需要知道有一棵現(xiàn)成的目錄樹或者字典樹,我們如何在終端輸出它的形狀。

#define OID_MAX_LEN  64  struct node_backlog {     /* node to be backlogged */     struct mib_node *node;     /* the backtrack point, next to the orignal sub-index of the node, valid when >= 1, invalid == 0 */     int next_sub_idx; };  static inline void nbl_push(struct node_backlog *nbl, struct node_backlog **top, struct node_backlog **bottom) {     if (*top - *bottom< OID_MAX_LEN) {         (*(*top)++) = *nbl;     } }  static inline struct node_backlog * nbl_pop(struct node_backlog **top, struct node_backlog **bottom) {     return *top > *bottom? --*top : NULL; }  void mib_tree_dump(void) {     int level = 0;     oid_t id = 0;     struct mib_node *node = *dummy_root;      struct node_backlog nbl, *p_nbl = NULL;     struct node_backlog *top, *bottom, nbl_stack[OID_MAX_LEN];      top = bottom = nbl_stack;      for (; ;) {         if (node != NULL) {             /* Fetch the pop-up backlogged node's sub-id. If not backlogged, set 0. */             int sub_idx = p_nbl != NULL ? p_nbl->next_sub_idx : 0;             /* Reset backlog for the node has gone deep down */             p_nbl = NULL;              /* Backlog the node */             if (is_leaf(node) || sub_idx + 1 >= node->sub_id_cnt) {                 nbl.node = NULL;                 nbl.next_sub_idx = 0;             } else {                 nbl.node = node;                 nbl.next_sub_idx = sub_idx + 1;             }             nbl_push(*nbl, *top, *bottom);             level++;              /* Draw lines as long as sub_idx is the first one */             if (sub_idx == 0) {                 int i;                 for (i = 1; i < level; i++) {                     if (i == level - 1) {                         printf("%-8s", "+-------");                     } else {                         if (nbl_stack[i - 1].node != NULL) {                             printf("%-8s", "|");                         } else {                             printf("%-8s", " ");                         }                     }                 }                 printf("%s(%d)\n", node->name, id);             }              /* Go deep down */             id = node->sub_id[sub_idx];             node = node->sub_ptr[sub_idx];         } else {             p_nbl = nbl_pop(*top, *bottom);             if (p_nbl == NULL) {                 /* End of traversal */                 break;             }             node = p_nbl->node;             level--;         }     } } 

代碼不算復雜,就講幾個要點

深度優(yōu)先遍歷要利用回溯點,就是走到一個分支的盡頭后,上溯到原先路過的某個位置,從另一個分支繼續(xù)遍歷,如果回溯到根節(jié)點,就說明遍歷結束了,所以,回溯點是必須要記錄的。問題是記錄哪個位置呢?以二叉樹為例,遍歷了左子樹后,接下來遍歷的就是右子樹,所以回溯點是右孩子;對于多叉樹,遍歷第N個分支后,接下來要遍歷N+1分支,所以回溯點是N+1;如果遍歷完最后一個分支,則需要繼續(xù)上溯尋找回溯點了。所以呢,我們就用sub_idx + 1來記錄回溯點,我們還可以利用這個屬性做個分類,值大于等于1時,回溯點有效,值等于0,回溯點無效。

關于log堆棧操作,這里使用了二級指針的技巧。這個堆棧十分小巧,所以利用函數(shù)局部變量做存儲也未嘗不可,還有不需要對外暴露數(shù)據(jù)的好處。那么對于堆棧指針,就需要傳遞二次指針來改變它。比如我們看入棧操作:

(*(*top)++) = *nbl; 

這是將log對象拷貝給top指向位置,然后將top指針上移,top和bottom的差值就是堆棧元素的數(shù)目。由于top是二級指針,所以被賦值的是**top,指針移動就是(*top)++。再來看出棧操作:

return --*top; 

先將top下移一個單位,然后返回所指向的log對象,也就是*top。

接下來該深入講解套路了,首先,根節(jié)點設置成了dummy,這是一個虛擬節(jié)點,是為了保證最上層只有一個節(jié)點而使用的編碼技巧,好比tree命令輸出目錄樹總是從當前目錄“.”開始。由于第一次進入循環(huán),log堆棧為空,不存在所謂回溯點,我們將回溯位置索引設為0,這有兩重含義,一來表示該回溯點無效或不存在,二來既然沒有回溯,那么接下來就從當前節(jié)點的第一個分支開始遍歷。

然后我們將遍歷過的節(jié)點壓棧,這里也是有區(qū)分的:如果當前是葉子節(jié)點,或者所有分支都遍歷完了,那么應該繼續(xù)上溯去尋找回溯點,我們就將回溯點設為無效后壓棧;否則就將當前節(jié)點設為回溯點,并記錄位置索引后壓棧。

畫線輸出部分稍后講。我們根據(jù)前面獲取的索引sub_idx進入下一層,直到觸底回溯,這時從log堆棧彈出回溯點,pop有三種情況:由于第一個壓棧為根節(jié)點,堆棧為空表示回溯到原點,也就標志著整個遍歷結束,退出循環(huán);否則查看回溯點是否為NULL,如果空如前所述繼續(xù)上溯;如果存在有效回溯點,則將回溯位置索引取出,繼續(xù)下一輪遍歷循環(huán)。

最后講終端輸出。前面說過每一行從左至右的輸出的是樹的層次遍歷,其實就是遍歷log堆棧;換行輸出就是樹的分支遍歷,就是每一輪循環(huán)。輸出內容主要是三個符號:縮進、分支和節(jié)點內容。我們作如下策略:

  • 縮進:當堆棧里回溯點無效,則不存在分支,打印空格,八個字符對齊;
  • 分支:當堆棧里回溯點有效,表示存在分支,打印“|”和空格,八個字符對齊;
  • 節(jié)點:當堆棧遍歷到最后一個元素,表示后面將要輸出節(jié)點內容,打印“+---”,八個字符對齊,后面跟節(jié)點內容。

當然你也可以自定義打印策略以便輸出更美觀。好了,說了一大堆,看效果吧,運行程序,一目了然。

<center>MIB樹</center>

B+樹

代碼在此。B+樹是關系數(shù)據(jù)庫常用的底層數(shù)據(jù)結構,實現(xiàn)起來相當恐怖,所幸本文不講這些,這里只是將B+樹作為多叉樹示范如何打印,特別是葉子節(jié)點和非葉子節(jié)點本身定義不同的情況下。從輸出實現(xiàn)上我們發(fā)現(xiàn),log對象記錄的只是節(jié)點的指針和回溯位置,同數(shù)據(jù)節(jié)點本身沒有關系。我們幾乎可以原封不動地把上面的代碼搬過來,運行效果如下:

</center> B+樹 </center>

從形狀上可以看到B+樹的真實數(shù)據(jù)都存儲在葉子節(jié)點,而且整棵樹是平衡的。

紅黑樹(二叉樹)

代碼在此。理解了多叉樹的實現(xiàn),二叉樹不過是一種特殊簡化形式罷了。本文挑選了紅黑樹為代表,代碼自己懶得寫了,直接拿Nginx源碼。

觀察得出,二叉樹關于回溯點的位置其實只有右邊分支,也就是說回溯位置索引只有一個值,就是1。這樣一來我們可以做個簡化,將左分支索引設為0表示無效回溯位置,右分支索引設為1表示有效回溯位置,代碼可以這樣寫:

#define RBTREE_MAX_LEVEL   64 #define RBTREE_LEFT_INDEX  0 #define RBTREE_RIGHT_INDEX 1  void rbtree_dump(struct rbtree *tree) {     int level = 0;     struct rbnode *node = tree->root, *sentinel = tree->sentinel;     struct node_backlog nbl, *p_nbl = NULL;     struct node_backlog *top, *bottom, nbl_stack[RBTREE_MAX_LEVEL];      top = bottom = nbl_stack;      for (; ;) {         if (node != sentinel) {             /* Fetch the pop-up backlogged node's sub-id. If not backlogged, set 0. */             int sub_index = p_nbl != NULL ? p_nbl->next_sub_idx : RBTREE_LEFT_INDEX;             /* backlog should be reset since node has gone deep down */             p_nbl = NULL;              /* Backlog the node */             if (is_leaf(node, sentinel) || sub_index == RBTREE_RIGHT_INDEX) {                 nbl.node = sentinel;                 nbl.next_sub_idx = RBTREE_LEFT_INDEX;             } else {                 nbl.node = node;                 nbl.next_sub_idx = RBTREE_RIGHT_INDEX;             }             nbl_push(&nbl, &top, &bottom);             level++;              /* Draw lines as long as sub_idx is the first one */             if (sub_index == RBTREE_LEFT_INDEX) {                 /* Print intent, branch and node content... */             }              /* Move down according to sub_idx */             node = sub_index == RBTREE_LEFT_INDEX ? node->left : node->right;         } else {             /* Pop up the node backlog... */         }     } } 

讓我們看一看輸出效果……等等,我們發(fā)現(xiàn)對于二叉樹,右孩子在左孩子的下一行打印,視覺上有點不習慣是嗎?還好我貼心地將LEFT_INDEX和RIGHT_INDEX交換了一下次序,右孩子就先于左孩子輸出了,這樣一來你就可以歪著腦袋直觀地看二叉樹了(笑),同時我們還知道,“翻轉”一棵二叉樹是多么容易(笑)。

<center>紅黑樹</center>

工欲善其事,必先利其器。學會了樹形結構打印工具,針對這樣的數(shù)據(jù)結構,只有你寫不了的,沒有你寫不對的。最后給出一個思考題:如何用遞歸形式實現(xiàn)打印樹形結構?(提示:利用參數(shù)傳遞)

參考源碼

目錄樹 B+樹 紅黑樹


責任編輯:王雪燕 來源: 開源中國社區(qū)
相關推薦

2023-05-04 07:34:37

Rust代碼CPU

2025-05-22 07:40:32

2021-12-16 06:21:16

React組件前端

2009-09-27 13:57:19

Hibernate樹形

2018-01-10 22:19:44

2023-11-27 07:10:06

日志中間件

2020-08-21 13:40:17

Python代碼人體膚色

2020-03-26 12:38:15

代碼節(jié)點數(shù)據(jù)

2015-02-09 10:43:00

JavaScript

2019-05-05 09:46:01

Python代碼神經(jīng)網(wǎng)絡

2021-12-20 14:22:07

Linux打印文件

2023-02-01 22:40:38

shellDocker

2015-09-01 16:26:18

Linux內核

2020-07-20 09:20:48

代碼geventPython

2024-09-19 08:22:41

2018-11-26 18:57:58

Python數(shù)據(jù)分析爬取

2020-04-10 12:25:28

Python爬蟲代碼

2015-10-10 14:33:55

2010-04-09 18:23:48

Unix操作系統(tǒng)

2023-12-08 09:15:53

Java單表樹形結構Tree
點贊
收藏

51CTO技術棧公眾號

免费在线观看一区二区| 亚洲第一av网| 伊人久久av导航| 国产精品xxxxxx| 欧美一区二区三区高清视频| 欧美在线观看一区二区| 亚洲一区二区三区免费观看| 69成人免费视频| 欧洲杯足球赛直播| 欧美日韩国产天堂| 99热都是精品| 亚洲精品国产片| 国产亚洲一区在线| 伊人久久久久久久久久| www在线观看免费| 欧美色18zzzzxxxxx| 日韩高清一级片| 久久伊人精品一区二区三区| 亚欧精品在线视频| jizz一区二区三区| 国产欧美日韩中文久久| 国产专区欧美专区| 国产一级在线播放| 欧美gay男男猛男无套| 亚洲黄色有码视频| 中文字幕日韩久久| 亚洲成人av观看| 亚洲第一在线综合网站| 亚洲免费av网| 国产黄色免费在线观看| 成人一区在线看| 国产欧美一区二区三区四区| 国产高清中文字幕| 黄色成人在线网址| 久久av在线看| 九一在线免费观看| 亚洲调教一区| 亚洲第一精品夜夜躁人人爽| 91丨porny丨九色| av在线播放一区| 色综合色综合色综合色综合色综合 | 久久精品日产第一区二区三区乱码 | 好吊色视频一区二区三区| 日韩精品第二页| 在线日韩一区二区| 亚洲中文字幕无码不卡电影| segui88久久综合9999| 一区二区国产盗摄色噜噜| 中文字幕欧美日韩一区二区| 成人免费视频| 国产欧美日韩在线| 视频一区二区精品| 国产爆初菊在线观看免费视频网站 | 户外极限露出调教在线视频| 99精品国产热久久91蜜凸| www.久久艹| 精品久久久免费视频| 国产一区二区三区不卡在线观看 | 久久久久久电影| 久久亚洲高清| 国产午夜视频在线观看| 久久免费视频一区| 日本在线免费观看一区| 国产视频第一页在线观看| 国产亚洲短视频| 亚洲欧美成人一区| 日本暖暖在线视频| 最新成人av在线| 成年人免费观看的视频| 色开心亚洲综合| 日韩毛片精品高清免费| 加勒比海盗1在线观看免费国语版| 男人和女人做事情在线视频网站免费观看| 国产精品美女一区二区| 亚洲欧洲在线一区| 黄色精品在线观看| 亚洲午夜久久久| 久久精品国产精品亚洲色婷婷| 午夜裸体女人视频网站在线观看| 午夜精品成人在线| 亚洲五月天综合| 深夜福利亚洲| 精品精品欲导航| 在线免费观看日韩av| 日韩国产欧美| 欧美精品在线看| 日本中文字幕免费| 蜜臀精品久久久久久蜜臀| 国产欧美婷婷中文| 免费国产精品视频| 国产日产欧美一区二区三区| 天堂√在线观看一区二区| 操你啦视频在线| 精品久久久国产| 一路向西2在线观看| 日本在线一区二区三区| 精品无人国产偷自产在线| 超碰97av在线| 在线成人h网| 国产精品国内视频| 国产黄色av网站| 91麻豆国产福利精品| 亚洲欧美日韩在线综合 | 日日噜噜夜夜狠狠| 日韩三级网址| 亚洲天堂网在线观看| 午夜爱爱毛片xxxx视频免费看| 亚洲乱码久久| 成人福利在线观看| 可以直接在线观看的av| 亚洲精品成a人| 激情内射人妻1区2区3区 | 91九色美女在线视频| 欧美在线观看18| 国产真实乱人偷精品| 91欧美国产| 欧美一乱一性一交一视频| 99国产成人精品| 久久九九影视网| 妺妺窝人体色777777| 男人天堂久久| 亚洲乱码av中文一区二区| 国产盗摄x88av| 青青草一区二区三区| 精品国产一区二区三区日日嗨| 蜜桃视频在线观看免费视频网站www | 亚洲福利在线播放| 天天鲁一鲁摸一摸爽一爽| 亚洲欧美激情诱惑| 国产在线精品一区二区三区》| 久热国产在线| 欧美三级资源在线| 91中文字幕永久在线| 亚洲激情一区| 99久久免费国| caopon在线免费视频| 欧美三级日韩在线| 中国女人特级毛片| 亚洲在线观看| 精品国产乱码一区二区三区四区 | 91精品国产91久久久久久| 国产高清免费在线观看| 亚洲免费资源在线播放| 亚洲美女爱爱视频| 日韩美女一区二区三区在线观看| 国产精品成人av在线| 日韩精品一二| 欧美日韩亚洲激情| 欧美肉大捧一进一出免费视频| 狠狠爱成人网| 国产精选一区二区| 2018av在线| 亚洲精品久久久一区二区三区| 国产精品18p| 成人av电影免费观看| 91黄色在线看| 精品国产午夜肉伦伦影院| 欧美国产日韩在线| 日韩中文字幕免费观看| 婷婷国产在线综合| 无码人妻精品一区二区三区温州| 国产亚洲毛片在线| 欧美日韩精品久久| xxxxx.日韩| 久久天堂电影网| av中文字幕播放| 亚洲妇女屁股眼交7| 国产老熟女伦老熟妇露脸| 香蕉久久久久久久av网站| 欧洲精品亚洲精品| 91麻豆精品| 欧美大片免费观看| 亚洲aaaaaaa| 欧美在线视频不卡| 国产精品精品软件男同| 国产电影精品久久禁18| 少妇人妻大乳在线视频| 亚洲第一论坛sis| 国产精品视频自在线| 国产精品一区二区三区视频网站| 日韩你懂的在线观看| 国产成人愉拍精品久久| 国产午夜亚洲精品理论片色戒| 色www免费视频| 欧美区一区二| 蜜桃成人免费视频| 国产精品诱惑| 欧美精品国产精品日韩精品| 蜜桃免费在线| 91精品国产综合久久香蕉的特点| 免费网站看av| 国产欧美一区二区精品性色| 中文字幕55页| 欧美亚洲免费| 99久热在线精品视频| 欧美三级电影在线| 成人精品久久久| 激情国产在线| 久久精品久久久久久国产 免费| 日韩在线观看视频网站| 欧美吞精做爰啪啪高潮| 久久网中文字幕| 国产清纯白嫩初高生在线观看91 | 99精品视频一区二区三区| 青青在线视频免费| 亚洲午夜精品一区二区国产| 九九九久久久| 国产一区二区视频在线看| 国产91精品高潮白浆喷水| 大地资源网3页在线观看| 亚洲美女喷白浆| 亚洲第一色网站| 欧美午夜不卡在线观看免费| 激情五月色婷婷| 亚洲欧美另类小说| 亚洲av毛片基地| 99精品国产一区二区三区不卡| 亚洲va综合va国产va中文| 久久国产66| 缅甸午夜性猛交xxxx| 欧美99久久| 亚洲一区二区高清视频| 亚洲免费专区| 国产亚洲精品自在久久| 日韩08精品| 成人亲热视频网站| 日本成人一区二区| 国产精品久久久久99| 成人性生交大片免费观看网站| 欧美国产日韩中文字幕在线| 欧美日韩在线资源| 中文字幕日韩在线视频| 嫩草研究院在线观看| 亚洲韩国青草视频| 欧美 日韩 国产 成人 在线| 欧美一区二区视频在线观看2020| 国产精品无码粉嫩小泬| 欧美丝袜一区二区| 久久黄色精品视频| 精品日本高清在线播放| 日韩精品成人在线| 精品国产精品三级精品av网址| 伊人365影院| 亚洲国产sm捆绑调教视频| 激情五月婷婷小说| 亚洲一区二区视频| 久久国产精品二区| 亚洲精品日韩一| 99视频只有精品| 亚洲精品成人悠悠色影视| 九九热这里有精品视频| 一区二区三区四区不卡视频| 欧美日韩亚洲国产另类| 亚洲激情一二三区| 久久这里只有精品免费| 亚洲高清视频中文字幕| 日韩少妇高潮抽搐| 欧美视频第一页| 亚洲欧美综合另类| 在线免费视频一区二区| 中文字幕av影视| 欧美久久久久免费| 国产女人18毛片水18精| 日韩欧美国产电影| 丁香花免费高清完整在线播放| 亚洲成年网站在线观看| 污污的视频网站在线观看| 亚洲欧美精品在线| 成年人在线观看| 久久视频在线播放| 福利成人导航| 浅井舞香一区二区| 国产精品第一| 99精彩视频在线观看免费| 国产福利资源一区| 欧美在线一区二区三区四区| 999国产精品999久久久久久| 免费成人深夜夜行网站视频| 亚洲激情影院| 国产福利影院在线观看| 国产福利一区二区| 特级西西人体wwwww| 国产午夜三级一区二区三| 麻豆天美蜜桃91| 欧美日韩国产丝袜另类| 中文字幕无码乱码人妻日韩精品| 555www色欧美视频| 婷婷在线免费视频| 中文字幕精品一区久久久久| 91麻豆一二三四在线| 欧美在线不卡区| 99久久这里有精品| 精品乱码一区| 国产精品99在线观看| 青青草视频在线免费播放| 久久成人免费电影| 熟女丰满老熟女熟妇| 国产精品成人免费| 午夜精品三级久久久有码| 欧美日韩成人综合天天影院 | 一个色综合导航| 中文字幕资源网在线观看| 人人澡人人澡人人看欧美| 欧美高清一级片| 欧美日韩系列| 亚洲无线视频| 九九精品久久久| 91一区一区三区| 日韩女优一区二区| 在线观看av一区| 无码国产伦一区二区三区视频| 精品国产自在精品国产浪潮| 在线观看欧美日韩电影| 97视频热人人精品| 日韩成人免费| 男人天堂网视频| 粉嫩av一区二区三区| 中文字幕美女视频| 色www精品视频在线观看| 国产香蕉在线观看| 精品中文字幕乱| 99久久999| 亚洲一区精品视频| 日韩电影在线一区二区三区| 国产精品入口麻豆| 亚洲免费电影在线| 亚洲一区精品在线观看| 亚洲欧洲一区二区三区久久| 9999精品成人免费毛片在线看| 亚洲在线免费观看| 久久久久久久久久久9不雅视频| 青青在线视频免费| 久久婷婷久久一区二区三区| 日韩精品一区二区三| 欧美精品一区二区不卡| 在线中文字幕电影| 亚洲r级在线观看| 亚洲精品一区二区在线看| 天天干天天干天天干天天干天天干| 久久综合资源网| 在线观看免费国产视频| 精品av久久707| 2021天堂中文幕一二区在线观| 99热99热| 伊人久久大香线蕉av超碰演员| 麻豆传媒在线看| 亚洲自拍另类综合| 欧美性受xxxx狂喷水| 国内精品久久久久久久| 成人另类视频| 黄网站欧美内射| 99r国产精品| 久久精品国产成人av| 国产丝袜一区二区三区| 精品3atv在线视频| 亚洲国产精品www| 麻豆91小视频| 色欲一区二区三区精品a片| 欧美一区二区三区公司| 岛国毛片av在线| 精品久久久久久综合日本| 99精品视频免费全部在线| 日本黄色特级片| 欧美亚洲国产一区在线观看网站 | 中文字幕巨乱亚洲| 一二三区中文字幕| 欧美超级乱淫片喷水| 超碰97久久国产精品牛牛| 自拍日韩亚洲一区在线| 久久久亚洲高清| 一区二区三区免费在线| 欧美美女15p| 任你弄精品视频免费观看| 狠狠热免费视频| 亚洲特黄一级片| 色婷婷av一区二区三区之红樱桃| 2020欧美日韩在线视频| 欧美视频网址| av在线网站免费观看| 午夜激情一区二区三区| avtt在线播放| y111111国产精品久久婷婷| 亚洲一区自拍| 国产色无码精品视频国产| 亚洲精品国产综合久久| 8av国产精品爽爽ⅴa在线观看 | 人妻丰满熟妇av无码久久洗澡| 日本乱人伦一区| 2024最新电影免费在线观看| 九九九热999| 久草中文综合在线| 国产情侣在线视频| 色一情一乱一区二区| 国产精伦一区二区三区| 污片在线免费看| 亚洲不卡av一区二区三区| 午夜伦全在线观看| 韩国成人一区| 国内精品免费在线观看| 久久青青草视频|