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

如何在 Go 中對依賴圖進行排序

開發 后端
最近,我在思考在軟件工程中遇到的許多重要問題可以歸結為幾個簡單的問題。只要看看任何關于算法的書,其中的大部分都會是排序或搜索集合的一些變體。

[[433885]]

大家好,我是程序員幽鬼。

最近,我在思考在軟件工程中遇到的許多重要問題可以歸結為幾個簡單的問題。只要看看任何關于算法的書,其中的大部分都會是排序或搜索集合的一些變體。谷歌的存在是因為“哪些文檔包含這些短語?”是一個真正難以解決的問題(好吧,這極大地簡化了 Google 產品的龐大范圍,但基本思想仍然成立)。

01 什么是拓撲排序?

在我的職業生涯中,我一次又一次遇到的常見問題之一就是對依賴圖的節點進行拓撲排序。換句話說,給定一些有向無環圖 — 想想可以依賴于其他軟件包或大型公司項目中的任務的軟件包 — 對它們進行排序,以便列表中的任何項目都不會依賴于列表中后面出現的任何內容。假設我們正在制作蛋糕,在開始之前,我們需要一些原料。讓我們來簡化一下,說我們只需要雞蛋和面粉。嗯,要吃雞蛋,我們需要雞(相信我,我在這里不是開玩笑),要吃面粉,我們需要谷物。雞也需要谷物作為飼料,谷物需要土壤和水才能生長。我們考慮表達所有這些依賴關系的圖表:

The dependency graph of cake

該圖的一種可能的拓撲順序是:

  1. []string{"soil""water""grain""chickens""flour""eggs""cake"

但是,還有其他可能的拓撲順序:

  1. []string{"water""soil""grain""flour""chickens""eggs""cake"

我們也可以把面粉放在雞蛋后面,因為唯一依賴雞蛋的就是蛋糕。由于我們可以重新排列項目,我們還可以并行完成其中一些項目,同時保持任何項目都不會出現在依賴于它的任何東西之前。例如,通過添加一層嵌套,我們可以表明內部切片中的所有內容都獨立于該切片中的其他任何內容:

  1. [][]string{ 
  2.     {"soil""water"}, 
  3.     {"grain"}, 
  4.     {"chickens""flour"}, 
  5.     {"eggs"}, 
  6.     {"cake"}, 

從這個圖中,我們得到了一個很好的“執行計劃”,用于為蛋糕準備依賴項。首先,我們需要找到一些土壤和水。接下來,我們種植谷物。然后,我們同時養一些雞和做面粉,收集雞蛋。最后,我們可以做蛋糕了!對于小于四歲的人來說,這似乎是一項艱巨的工作,但好的事情需要時間。

02 構建依賴圖

現在我們了解了要做什么,讓我們考慮如何編寫一些能夠構建這種依賴項列表的代碼。我們當然需要跟蹤元素本身,我們需要跟蹤什么取決于什么。為了使兩者都“取決于什么X?” 和“X取決于什么?” 高效,我們將跟蹤兩個方向的依賴關系。

我們已經足夠了解開始編寫代碼所需的內容:

  1. // A node in this graph is just a string, so a nodeset is a map whose 
  2. // keys are the nodes that are present. 
  3. type nodeset map[string]struct{} 
  4.  
  5. // depmap tracks the nodes that have some dependency relationship to 
  6. // some other node, represented by the key of the map. 
  7. type depmap map[string]nodeset 
  8.  
  9. type Graph struct { 
  10.  nodes nodeset 
  11.  
  12.  // Maintain dependency relationships in both directions. These 
  13.  // data structures are the edges of the graph. 
  14.  
  15.  // `dependencies` tracks child -> parents. 
  16.  dependencies depmap 
  17.  // `dependents` tracks parent -> children. 
  18.  dependents depmap 
  19.  // Keep track of the nodes of the graph themselves. 
  20.  
  21. func New() *Graph { 
  22.  return &Graph{ 
  23.   dependencies: make(depmap), 
  24.   dependents:   make(depmap), 
  25.   nodes:        make(nodeset), 
  26.  } 

這種數據結構應該適合我們的目的,因為它包含我們需要的所有信息:節點、“依賴”邊和“依賴于”邊。現在讓我們考慮創建用于向圖形添加新依賴關系的 API。所有我們需要的是一個聲明的方法,一些節點依賴于另一個,就像這樣:graph.DependOn("flour", "grain")。有幾種情況我們要明確禁止。首先,一個節點不能依賴于自己,其次,如果flour依賴于grain,那么grain一定不能依賴于flour,否則我們會創建一個無限的依賴循環。有了這個,讓我們編寫Graph.DependOn()方法。

  1. func (g *Graph) DependOn(child, parent string) error { 
  2.  if child == parent { 
  3.   return errors.New("self-referential dependencies not allowed"
  4.  } 
  5.  
  6.  // The Graph.DependsOn() method doesn't exist yet. 
  7.  // We'll write it next
  8.  if g.DependsOn(parent, child) { 
  9.   return errors.New("circular dependencies not allowed"
  10.  } 
  11.  
  12.  // Add nodes. 
  13.  g.nodes[parent] = struct{}{} 
  14.  g.nodes[child] = struct{}{} 
  15.  
  16.  // Add edges. 
  17.  addNodeToNodeset(g.dependents, parent, child) 
  18.  addNodeToNodeset(g.dependencies, child, parent) 
  19.  
  20.  return nil 
  21.  
  22. func addNodeToNodeset(dm depmap, key, node string) { 
  23.  nodes, ok := dm[key
  24.  if !ok { 
  25.   nodes = make(nodeset) 
  26.   dm[key] = nodes 
  27.  } 
  28.  nodes[node] = struct{}{} 

一旦我們實現,這將有效地為我們的圖表添加依賴關系Graph.DependsOn()。我們可以很容易地判斷一個節點是否直接依賴于其他某個節點,但我們也想知道是否存在傳遞依賴。例如,由于flour依賴于grain并且grain依賴于soil,因此也flour依賴于soil。這將要求我們獲取節點的直接依賴項,然后對于這些依賴項中的每一個,獲取其依賴項等等,直到我們停止發現新的依賴項。用計算機科學術語來說,我們正在計算一個固定點,以在我們的圖上找到“DependsOn”關系的傳遞閉包。

  1. func (g *Graph) DependsOn(child, parent string) bool { 
  2.  deps := g.Dependencies(child) 
  3.  _, ok := deps[parent] 
  4.  return ok 
  5.  
  6. func (g *Graph) Dependencies(child string) nodeset { 
  7.  if _, ok := g.nodes[root]; !ok { 
  8.   return nil 
  9.  } 
  10.   
  11.  out := make(nodeset) 
  12.  searchNext := []string{root} 
  13.  for len(searchNext) > 0 { 
  14.   // List of new nodes from this layer of the dependency graph. This is 
  15.   // assigned to `searchNext` at the end of the outer "discovery" loop. 
  16.   discovered := []string{} 
  17.   for _, node := range searchNext { 
  18.    // For each node to discover, find the next nodes. 
  19.    for nextNode := range nextFn(node) { 
  20.     // If we have not seen the node before, add it to the output as well 
  21.     // as the list of nodes to traverse in the next iteration. 
  22.     if _, ok := out[nextNode]; !ok { 
  23.      out[nextNode] = struct{}{} 
  24.      discovered = append(discovered, nextNode) 
  25.     } 
  26.    } 
  27.   } 
  28.   searchNext = discovered 
  29.  } 
  30.   
  31.  return out 

03 對圖表進行排序

現在我們有了一個圖數據結構,可以考慮如何按照拓撲順序將節點取出。如果我們可以發現葉節點—即,節點本身對其他節點沒有依賴關系—那么我們可以重復獲取葉子并將它們從圖中移除,直到圖為空。在第一次迭代中,我們將找到獨立的元素,然后在隨后的每次迭代中,我們將找到僅依賴于已刪除元素的節點。最終結果將是一個按拓撲排序的獨立“層”節點的切片。

獲取圖的葉子很簡單。我們只需要找到在 dependencies 中沒有條目的節點。這意味著它們不依賴于任何其他節點。

  1. func (g *Graph) Leaves() []string { 
  2.  leaves := make([]string, 0) 
  3.  
  4.  for node := range g.nodes { 
  5.   if _, ok := g.dependencies[node]; !ok { 
  6.    leaves = append(leaves, node) 
  7.   } 
  8.  } 
  9.  
  10.  return leaves 

最后一塊拼圖實際上是計算圖的拓撲排序層。這也是最復雜的一塊。我們將遵循的一般策略是迭代地收集葉子并將它們從圖中刪除,直到圖為空。由于我們將對圖進行變異,因此我們希望對其進行克隆,以便在執行排序后原始圖仍然完好無損,因此我們將繼續實施該克隆:

  1. func copyNodeset(s nodeset) nodeset { 
  2.  out := make(nodeset, len(s)) 
  3.  for k, v := range s { 
  4.   out[k] = v 
  5.  } 
  6.  return out 
  7.  
  8. func copyDepmap(m depmap) depmap { 
  9.  out := make(depmap, len(m)) 
  10.  for k, v := range m { 
  11.   out[k] = copyNodeset(v) 
  12.  } 
  13.  return out 
  14.  
  15. func (g *Graph) clone() *Graph { 
  16.  return &Graph{ 
  17.   dependencies: copyDepmap(g.dependencies), 
  18.   dependents:   copyDepmap(g.dependents), 
  19.   nodes:        copyNodeset(g.nodes), 
  20.  } 

我們還需要能夠從圖中刪除一個節點和所有邊。刪除節點很簡單,就像從每個節點刪除出站邊一樣。然而,我們跟蹤兩個方向的每條邊的事實意味著我們必須做一些額外的工作來刪除入站記錄。我們將用于刪除所有邊的策略如下:

在 dependents 中查找節點 A 的條目。這為我們提供了依賴于 A 的節點集 。

對于這些節點中的每一個,在 dependencies 中找到條目。從 nodeset 中刪除A。

在 dependents 中刪除節點 A 的條目。

執行逆操作,在 dependencies 中查找節點 A 等。

借助一個允許我們從 depmap 條目中刪除節點的小實用程序,我們可以編寫從圖中完全刪除節點的方法。

  1. func removeFromDepmap(dm depmap, key, node string) { 
  2.  nodes := dm[key
  3.  if len(nodes) == 1 { 
  4.   // The only element in the nodeset must be `node`, so we 
  5.   // can delete the entry entirely. 
  6.   delete(dm, key
  7.  } else { 
  8.   // Otherwise, remove the single node from the nodeset. 
  9.   delete(nodes, node) 
  10.  } 
  11.  
  12. func (g *Graph) remove(node string) { 
  13.  // Remove edges from things that depend on `node`. 
  14.  for dependent := range g.dependents[node] { 
  15.   removeFromDepmap(g.dependencies, dependent, node) 
  16.  } 
  17.  delete(g.dependents, node) 
  18.  
  19.  // Remove all edges from node to the things it depends on
  20.  for dependency := range g.dependencies[node] { 
  21.   removeFromDepmap(g.dependents, dependency, node) 
  22.  } 
  23.  delete(g.dependencies, node) 
  24.  
  25.  // Finally, remove the node itself. 
  26.  delete(g.nodes, node) 

最后,我們可以實現 Graph.TopoSortedLayers():

  1. func (g *Graph) TopoSortedLayers() [][]string { 
  2.  layers := [][]string{} 
  3.  
  4.  // Copy the graph 
  5.  shrinkingGraph := g.clone() 
  6.  for { 
  7.   leaves := shrinkingGraph.Leaves() 
  8.   if len(leaves) == 0 { 
  9.    break 
  10.   } 
  11.  
  12.   layers = append(layers, leaves) 
  13.   for _, leafNode := range leaves { 
  14.    shrinkingGraph.remove(leafNode) 
  15.   } 
  16.  } 
  17.  
  18.  return layers 

這種方法清楚地概述了我們對圖進行拓撲排序的策略:

  • 克隆圖,以便我們可以對其進行轉變。
  • 反復將圖的葉子收集到輸出的“層”中。
  • 收集后刪除每一層。
  • 當圖為空時,返回收集的圖層。

現在我們可以回到最初的蛋糕制作問題,以確保我們的圖為我們解決了這個問題:

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  "strings" 
  6.  
  7.  "github.com/kendru/darwin/go/depgraph" 
  8.  
  9. func main() { 
  10.  g := depgraph.New() 
  11.  g.DependOn("cake""eggs"
  12.  g.DependOn("cake""flour"
  13.  g.DependOn("eggs""chickens"
  14.  g.DependOn("flour""grain"
  15.  g.DependOn("chickens""grain"
  16.  g.DependOn("grain""soil"
  17.  g.DependOn("grain""water"
  18.  g.DependOn("chickens""water"
  19.  
  20.  for i, layer := range g.TopoSortedLayers() { 
  21.   fmt.Printf("%d: %s\n", i, strings.Join(layer, ", ")) 
  22.  } 
  23.  // Output
  24.  // 0: soil, water 
  25.  // 1: grain 
  26.  // 2: flour, chickens 
  27.  // 3: eggs 
  28.  // 4: cake 

所有這些工作都不是小菜一碟,但現在我們有了一個依賴圖,可以用來對幾乎任何東西進行拓撲排序。您可以在 GitHub 上找到[1]這篇文章的完整代碼。這個實現有一些明顯的限制,我想挑戰你改進它,以便它可以:

  • 存儲不是簡單字符串的節點
  • 允許單獨添加節點和邊/依賴信息
  • 產生用于調試的字符串輸出

原文鏈接:https://kendru.github.io/go/2021/10/26/sorting-a-dependency-graph-in-go/

參考資料

[1]在 GitHub 上找到: https://github.com/kendru/darwin/tree/main/go/depgraph

本文轉載自微信公眾號「幽鬼」,可以通過以下二維碼關注。轉載本文請聯系幽鬼公眾號。

 

責任編輯:武曉燕 來源: 幽鬼
相關推薦

2020-11-26 08:12:24

JavaScript對象數組

2021-09-02 22:52:16

ValueDictionary排序

2021-07-09 12:37:31

GoPython編程語言

2025-02-10 10:29:32

2016-12-01 15:43:41

Linuxls命令

2020-05-06 20:40:03

Go編程語言

2013-12-18 09:56:20

AngularJS測試

2020-11-25 12:20:08

Linuxps命令

2021-11-04 05:43:38

GoKartGo代碼靜態安全分析

2022-03-15 07:55:09

JavaScript線性儀表圖開發

2023-11-26 19:06:13

GO測試

2022-11-11 09:01:08

SwiftUI條形圖子視圖

2023-11-30 20:51:26

多子圖布局matplotlib

2021-05-17 14:02:38

Swift 多重排序

2024-05-06 13:34:28

WireGoogleGo

2023-06-15 13:01:07

JavaPythonJavaScript

2022-09-19 11:42:21

Go優化CPU

2014-04-02 13:27:29

iOSNSArray對象

2023-06-06 16:10:11

2021-07-02 07:18:19

Goresults通道類型
點贊
收藏

51CTO技術棧公眾號

美美哒免费高清在线观看视频一区二区 | 日本日本精品二区免费| 偷偷操不一样的久久| 欧美激情在线精品一区二区三区| 欧美网站大全在线观看| 老司机午夜网站| 天堂在线视频网站| 亚洲永久免费精品| 一区二区欧美在线| 无码人妻一区二区三区一| 女生影院久久| 亚洲美女区一区| 久久亚洲国产精品日日av夜夜| 这里只有久久精品视频| 亚洲欧美综合| 在线看日韩欧美| 亚洲熟女一区二区三区| 亚洲成人va| 悠悠色在线精品| 婷婷五月色综合| 国产小视频一区| 久久精品99久久久| 欧美亚洲激情在线| 一区二区成人免费视频| 欧州一区二区| 日韩精品在线观看视频| 在线观看视频在线观看| 成人1区2区| 欧美日韩午夜剧场| 路边理发店露脸熟妇泻火| 国产毛片av在线| 成人动漫精品一区二区| 91美女片黄在线观| 日韩中文字幕高清| 国产精品夜夜夜| 欧美国产视频一区二区| 北条麻妃在线观看视频| 国产伦精品一区二区三区千人斩| 亚洲精品动漫100p| 无码人妻一区二区三区免费n鬼沢| 祥仔av免费一区二区三区四区| 欧美网站在线观看| 精品国产一二三四区| 男人添女人下部高潮视频在线观看| 国产精品久久久久久久久久免费看 | 国产精品亚洲成在人线| 日本久久电影网| 男人靠女人免费视频网站| rebdb初裸写真在线观看| 一区二区三区高清在线| 玖玖精品在线视频| а√中文在线8| 亚洲人吸女人奶水| 欧美日韩在线免费观看视频| 91美女视频在线| 中文字幕第一区综合| 视频一区二区三区免费观看| 国产黄在线观看| 日本一区免费视频| 亚洲v国产v在线观看| 97在线观看免费观看高清| 国产欧美日韩在线观看| 亚欧洲精品在线视频免费观看| 黄色影院在线播放| 中文字幕欧美三区| 亚洲精品一区二区三| 91在线直播| 亚洲同性gay激情无套| 最近中文字幕免费mv| av片在线观看免费| 亚洲成av人在线观看| 日韩免费视频播放| 香蕉视频亚洲一级| 永久免费av在线| 国产日韩亚洲欧美精品| 性欧美视频videos6一9| 欧美啪啪小视频| 男人的j进女人的j一区| 国产综合久久久久| 亚洲美女综合网| 337p粉嫩大胆色噜噜噜噜亚洲| 日韩jizzz| 成人日日夜夜| 亚洲va欧美va国产va天堂影院| 日本精品免费在线观看| 992tv国产精品成人影院| 欧美精品在线一区二区三区| 黄页网站在线看| 在线一级成人| 久久久国产精品x99av | 午夜激情一区二区三区| 欧美亚洲国产成人| 欧美一级做a| 精品久久免费看| 国产精品扒开腿做爽爽| 小处雏高清一区二区三区| 欧美激情在线一区| 波多野结衣视频网址| 国产电影精品久久禁18| 久久久精品动漫| 国产传媒在线播放| 欧美日韩午夜视频在线观看| 黄色片免费网址| 中文有码一区| 欧美国产日韩视频| 在线免费av网| a级高清视频欧美日韩| 一本久久a久久精品vr综合| heyzo高清在线| 欧美丝袜丝nylons| 欧美大喷水吹潮合集在线观看| 成人午夜av| 8x海外华人永久免费日韩内陆视频 | 欧美专区日韩视频| 99999精品| 任你躁在线精品免费| 色偷偷av亚洲男人的天堂| 国产精品9191| 精品一区二区三区在线视频| 韩国一区二区三区美女美女秀| 米奇777四色精品人人爽| 欧美色道久久88综合亚洲精品| 手机在线免费毛片| 精品视频免费| 欧洲中文字幕国产精品| 亚洲精品.www| 亚洲丝袜制服诱惑| 免费黄色一级网站| 亚州av日韩av| 国模极品一区二区三区| 99久久久国产精品无码免费| 国产丝袜欧美中文另类| 自慰无码一区二区三区| 亚洲精品在线a| 欧美精品免费看| 一级片在线免费观看视频| 久久久久9999亚洲精品| 好吊妞无缓冲视频观看| 国产乱论精品| 欧美激情久久久久| www久久久com| 亚洲欧美视频在线观看视频| 第一区免费在线观看| 日本欧美国产| 国产精品久久久久国产a级| 日韩在线免费看| 狠狠躁18三区二区一区| 捆绑凌虐一区二区三区| 日韩五码在线| 免费国产一区| 欧美二三四区| 国产亚洲在线播放| 亚洲视屏在线观看| 国产精品视频你懂的| 中文字幕亚洲乱码| 四虎8848精品成人免费网站| 国产精品一区二区三区久久久| eeuss影院在线观看| 欧美午夜片在线看| 日本爱爱小视频| 国产精品一区免费视频| 日本aa在线观看| www.久久东京| 91av在线看| 激情小视频在线观看| 欧美午夜精品久久久久久孕妇| 91成人在线免费视频| 人禽交欧美网站| 99re99热| 999久久久久久久久6666| 久久99国产综合精品女同| 亚洲第一免费视频| 午夜国产不卡在线观看视频| av无码一区二区三区| 奶水喷射视频一区| 色狠狠久久av五月综合| 爱情电影网av一区二区| 欧美激情综合亚洲一二区| 污视频网站在线播放| 日本黄色一区二区| 男人在线观看视频| 波多野结衣亚洲一区| 免费看a级黄色片| 欧美大片aaaa| 国产精品一区视频| 神马久久资源| 久久这里有精品视频| 三级网站在线看| 欧美亚洲一区二区在线观看| 成年人av电影| 久久久精品综合| 亚洲一区二区中文字幕在线观看| 亚洲国产一区二区精品专区| 日本不卡在线播放| 亚洲精品黑牛一区二区三区| 日韩美女在线观看| 18网站在线观看| 亚洲视频在线免费看| 99热精品在线播放| 欧洲视频一区二区| av资源吧首页| 国产精品人妖ts系列视频| 极品人妻一区二区| 日本中文字幕不卡| 麻豆tv在线播放| 国产精品国产一区| 麻豆精品传媒视频| 日本久久伊人| 国产精品专区h在线观看| 国产伦子伦对白在线播放观看| 色妞色视频一区二区三区四区| 欧美在线精品一区二区三区| 欧美日本一区二区| 免费视频久久久| 亚洲成av人片一区二区梦乃| 小泽玛利亚一区| 久久精品日韩一区二区三区| 岛国精品资源网站| 国产一区二区三区在线观看精品 | 亚洲精品乱码久久久久久久久久久久| 国内成+人亚洲+欧美+综合在线| 国产主播在线看| 在线电影一区| 大胆欧美熟妇xx| 99久久精品费精品国产| 日韩福利视频| 亚洲第一福利社区| 国产伦精品一区二区三区四区视频 | 国产吃瓜黑料一区二区| 九九视频精品免费| 九色porny自拍| 日韩电影在线免费看| 免费看国产曰批40分钟| 欧美黄污视频| 8x8x华人在线| 91精品久久久久久久蜜月| 天堂精品视频| 狠狠做深爱婷婷综合一区| 麻豆精品传媒视频| 伊人成综合网yiren22| 久久精品magnetxturnbtih| 91欧美极品| 动漫美女被爆操久久久| 91在线一区| 国产精品对白刺激久久久| 日本一区二区三区播放| 亚洲精品欧美一区二区三区| 先锋影音网一区二区| 国产有码一区二区| 看亚洲a级一级毛片| 成人写真福利网| 精品国产伦一区二区三区观看说明 | 在线成人激情黄色| av网站大全在线观看| 中文国产成人精品| 蜜桃视频在线观看www社区| www.亚洲一区| 狂野欧美性猛交xxxxx视频| 欧美黄色免费网站| av资源一区| 欧美亚洲另类激情另类| 美女网站视频一区| 国产精品日韩专区| 四虎国产精品成人免费影视| 亚洲bt天天射| 亚洲一区二区免费在线观看| 国产综合色一区二区三区| 同性恋视频一区| 秋霞在线观看一区二区三区 | 久久久无码中文字幕久...| 欧美在线观看天堂一区二区三区| 日韩欧美视频免费在线观看| 亚洲精品乱码| 国产一区视频免费观看| 另类欧美日韩国产在线| 久久久久久久久久毛片| 成人动漫精品一区二区| 国内精品卡一卡二卡三| 中文字幕一区二区日韩精品绯色| 精品视频一区二区在线观看| 精品久久久中文| 国产精品无码粉嫩小泬| 欧美一级国产精品| 神马久久精品| 中文字幕v亚洲ⅴv天堂| 好看的中文字幕在线播放| 日本三级久久久| 国产一区二区三区黄网站| 国产视频一区二区三区四区| 国产欧美一区| 黄色一级大片免费| 日韩精品亚洲专区| 超碰人人cao| 国产日产欧美一区| 久久久香蕉视频| 日本福利一区二区| 亚洲欧美高清视频| 亚洲性生活视频| 欧美极品少妇videossex| 国产精品h在线观看| 一区三区自拍| 亚洲黄色一区二区三区| 亚洲激情av| 日日干夜夜操s8| 91在线视频免费观看| 欧美精品久久久久久久久46p| 岛国精品视频在线播放| 99热这里只有精品99| 亚洲香蕉av在线一区二区三区| 丰满的护士2在线观看高清| 国产免费一区视频观看免费| 欧美高清视频看片在线观看 | 日韩一级欧洲| 伊人五月天婷婷| 国产欧美一区二区三区在线看蜜臀 | 男女无套免费视频网站动漫| 成人精品国产福利| 国产午夜手机精彩视频| 欧美在线免费视屏| 人妻91麻豆一区二区三区| 久久久精品一区二区| 第四色男人最爱上成人网| 国产色综合一区二区三区| 在线成人超碰| 美女少妇一区二区| 久久久久久久网| 国产极品美女高潮无套嗷嗷叫酒店 | 久久国产精品电影| 欧美国产视频| 亚洲 日韩 国产第一区| 久久久蜜桃一区二区人| 国产视频久久久久久| 亚洲二区在线视频| 午夜精品无码一区二区三区| 久久视频在线免费观看| 成人高清一区| 亚洲一区二区三区午夜| 日本欧美一区二区在线观看| 特级西西www444人体聚色| 色婷婷久久综合| 美州a亚洲一视本频v色道| 欧洲精品久久久| 久久成人高清| 亚洲性生活网站| 国产日韩精品久久久| 精品一区二三区| 伊人久久久久久久久久久| 久久91导航| 日韩国产精品一区二区| 秋霞av亚洲一区二区三| 女教师淫辱の教室蜜臀av软件| 欧美午夜不卡在线观看免费| 日本三级视频在线播放| 91免费版网站入口| 狠狠综合久久| 稀缺小u女呦精品呦| 五月天视频一区| 国产香蕉视频在线看| 国产精品福利在线| 久久一区91| 波多野结衣免费观看| 一区二区三区日韩精品视频| 刘亦菲久久免费一区二区| 97人人做人人爱| 蜜桃精品噜噜噜成人av| 制服丝袜综合网| 综合中文字幕亚洲| 免费观看国产精品| 欧美一区二区三区免费视| 不卡视频在线| 九九九久久久久久久| 五月天视频一区| 岛国在线大片| 亚洲一区中文字幕在线观看| 亚洲久久一区二区| 老牛影视av老牛影视av| 欧美精品日韩一本| av中文字幕在线看| 日本视频精品一区| 国产高清精品网站| 男女视频免费看| 一区二区欧美激情| 亚洲五码在线| 午夜激情福利在线| 亚洲柠檬福利资源导航| 偷拍自拍在线| 91欧美精品成人综合在线观看| 亚洲三级视频| 男人天堂资源网| 亚洲国产精品久久久久| 草莓视频成人appios| 欧美亚洲黄色片| 中文字幕久久午夜不卡| 国产小视频免费观看| 国产日韩精品在线播放| 亚洲一卡久久| 99久久婷婷国产综合| 亚洲午夜国产成人av电影男同| 亚洲一区二区三区四区电影| www.激情小说.com|