日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构 图论02 十字链表详解 代码

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构 图论02 十字链表详解 代码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

數(shù)據(jù)結(jié)構(gòu) 圖論01 鄰接矩陣、鄰接表 代碼
數(shù)據(jù)結(jié)構(gòu) 圖論02 十字鏈表詳解 代碼

閱讀之前請了解先了解鄰接表數(shù)據(jù)結(jié)構(gòu) 圖論01 鄰接矩陣、鄰接表 代碼

數(shù)據(jù)結(jié)構(gòu)

上面的數(shù)組+鏈表可以節(jié)約一些空間和方便增刪,但是我們要計算一個頂點的度還是比較麻煩,十字鏈表就是解決計算頂點入度(就是有多少條邊通向這個節(jié)點)的問題

頂點Vertex的結(jié)構(gòu)

  • data :頂點具體數(shù)據(jù)信息
  • firstIn:通向這個頂點的(豎向)邊鏈表的讀一個節(jié)點
  • firstOut:通向其他頂點的(橫向)邊的鏈表的第一個節(jié)點

邊edge的結(jié)構(gòu)

  • fromVertex:箭頭出發(fā)的頂點(比如A頂點)
  • toVertex:箭頭指向的頂點(B頂點)
  • fromEdge:指向目標點是fromVertex的邊,這里就是豎向鏈表的核心實現(xiàn)(綠色的2條邊DA,CA)
  • toEdge:以fromVertex為基礎(chǔ),指向其他頂點的邊(紅色的2條邊,AC,AB)
  • weight:權(quán)重

十字鏈表的結(jié)構(gòu)

為了解決計算頂點入度的問題,在橫向鏈表表示出度的基礎(chǔ)上(紅色的邊),加上一個豎向鏈表表示入度(綠色的邊),通過豎向鏈表可以輕松得到入度。

  • 紅色箭頭是橫向表示出度,(同理于鄰接鏈表)
  • 綠色箭頭是豎向表示入度(豎向鏈表是十字鏈表的關(guān)鍵)

代碼實現(xiàn)

Graph

import java.util.ArrayList;/*** 十字鏈表* @author Jarvan* @version 1.0* @create 2020/11/25 16:43*/ public class CrossLinkedListGraph<E> {class Vertex{E data;Edge firstIn;Edge firstOut;public Vertex(E data, Edge firstIn, Edge firstOut) {this.data = data;this.firstIn = firstIn;this.firstOut = firstOut;}}class Edge{int fromVertex;int toVertex;Edge fromEdge;Edge toEdge;int weight;public Edge(int fromVertex, int toVertex, Edge fromEdge, Edge toEdge, int weight) {this.fromVertex = fromVertex;this.toVertex = toVertex;this.fromEdge = fromEdge;this.toEdge = toEdge;this.weight = weight;}}private int numOfVertices;private int maxOfVertices;private ArrayList<Vertex> vertices;public CrossLinkedListGraph(int maxOfVertices) {this.maxOfVertices = maxOfVertices;this.vertices = new ArrayList<>(maxOfVertices);numOfVertices = 0;}public boolean putVertex(E data){if (numOfVertices < maxOfVertices){vertices.add(new Vertex(data,null,null));numOfVertices ++;return true;}return false;}public E getVertexData(int vertexIndex){if (vertexIndex<maxOfVertices){return vertices.get(vertexIndex).data;}return null;}/*** 插入邊,橫縱列表都要插入*/public boolean putEdge(int fromVertexIndex,int toVertexIndex,int weight){if (fromVertexIndex < maxOfVertices && toVertexIndex < maxOfVertices){Vertex fromVertex = vertices.get(fromVertexIndex);Edge newEdge = new Edge(fromVertexIndex,toVertexIndex,null,null,weight);//插入橫向鏈表if (fromVertex.firstOut == null) {fromVertex.firstOut = newEdge;//插入豎向鏈表return insertFromEdgeLinkedList(fromVertex.firstOut);}//遍歷元素然后將元素放到尾部Edge edge = fromVertex.firstOut;while (edge.toEdge != null) {edge = edge.toEdge;}edge.toEdge = newEdge;//插入豎向鏈表return insertFromEdgeLinkedList(edge.toEdge);}return false;}/*** 將插入豎向鏈表提升為一個方法*/private boolean insertFromEdgeLinkedList(Edge edge){if ( edge!=null){//獲得新增加的指向的頂點Vertex toVertex = vertices.get(edge.toVertex);if (toVertex.firstIn==null){//如果指向的頂點沒有豎向鏈表就直接將第一個邊賦值給豎向鏈表toVertex.firstIn = edge;return true;}Edge fromEdge = toVertex.firstIn;while (fromEdge.fromEdge!=null){fromEdge = fromEdge.fromEdge;}fromEdge.fromEdge = edge;return true;}return false;}public void print(){for (Vertex vertex : vertices) {Edge edge = vertex.firstOut;System.out.print(vertex.data+": ");while (edge!=null){System.out.print(vertices.get(edge.fromVertex).data+ " --> "+vertices.get(edge.toVertex).data+" weight="+edge.weight +"; ");edge = edge.toEdge ;}System.out.println();}}public void printVertexFromEdge(int fromVertex){System.out.println("====print vertex from edges====");Vertex vertex = vertices.get(fromVertex);Edge firstIn = vertex.firstIn;if (vertex.firstIn!=null){Edge fromEdge = vertex.firstIn;while (fromEdge!=null){//這里debug的時候錄為nullSystem.out.println(vertices.get(fromEdge.fromVertex).data+" --> "+vertices.get(fromEdge.toVertex).data);fromEdge = fromEdge.fromEdge;}}else {System.out.println("null of firstIn");}}}

test

CrossLinkedListGraph<String> graph = new CrossLinkedListGraph<>(4); graph.putVertex("A"); graph.putVertex("B"); graph.putVertex("C"); graph.putVertex("D");graph.putEdge(0,1,4); graph.putEdge(0,2,3); graph.putEdge(2,3,5); graph.putEdge(2,0,5); graph.putEdge(3,0,6); graph.putEdge(3,1,6); graph.print(); //獲得一個點的fromEdge然后打印 graph.printVertexFromEdge(0);

result

A: A --> B weight=4; A --> C weight=3; B: C: C --> D weight=5; C --> A weight=5; D: D --> A weight=6; D --> B weight=6; ====print vertex from edges==== C --> A D --> AProcess finished with exit code 0

**

數(shù)據(jù)結(jié)構(gòu)優(yōu)點缺點
鄰接矩陣二維數(shù)組,實現(xiàn)簡單,能同時求出頂點的出度和入度稀疏圖造成的空間浪費
鄰接表數(shù)組+鏈表,不會空間浪費不能同時求出出度和入度;對邊的操作需要2次
十字鏈表橫豎十字鏈表:可以同時求出出度和入度對邊的操作需要2次
鄰接多重表對邊的操作減少到了一次刪除較為復雜

備注:這里的鏈表插入是遍歷到鏈表尾部再插入,效率比較低下,建議使用”頭插法“

總結(jié)

以上是生活随笔為你收集整理的数据结构 图论02 十字链表详解 代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。