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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构与算法09 之图

發布時間:2025/3/20 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法09 之图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? 在計算機程序設計中,圖是最常用的結構之一。圖是一種與樹有些相像的數據結構,實際上,從數學意義上說,樹是圖的一種。然而在計算機程序設計中,圖的應用方式與樹不同。

??????? 前面討論的數據結構都有一個框架,這個框架都是由相應的算法設定的。比如說,二叉樹是那樣一個形狀,就是因為那樣的形狀使它更容易搜索數據和插入新數據,樹的邊表示了從一個節點到另一個節點的快捷方式。而圖通常有一個固定的形狀,這是由物理或抽象的問題所決定的。比如說,圖中節點表示城市,而邊表示城市間的航班線,這些都是固定的。即,圖的形狀取決于真實世界的具體情況。在圖中,我們稱節點為頂點。

?? ? ?? 在大多數情況下,頂點表示某個真實世界的對象,這個對象必須用數據項來描述。例如頂點代表城市,那么它需要存儲城市名字、海拔高度、地理位置等相關信息。因此通常用一個頂點類的對象來表示一個頂點。這里我們僅僅在頂點中存儲了一個字母來標識頂點,同時還有一個標志位,用來判斷該頂點有沒有被訪問過。

[java]?view plaincopy
  • class?Vertex?{?//頂點類??
  • ????public?char?label;??//label:?eg.'A'??
  • ????public?boolean?wasVisited;??
  • ????public?Vertex(char?lab)?{??
  • ????????label?=?lab;??
  • ????????wasVisited?=?false;??
  • ????}??
  • }??
  • ??????? 頂點對象能放在數組(這里用vertexList數組)中,然后用下標指示,也可以放在鏈表或其他數據結構中,但不論使用什么數據結構,存儲只為了使用方便,這與邊如何連接點沒有關系。

    ??????? 前面提到的樹的表示中,大多數情況下都是每個節點包含它的子節點的引用,也可以用數組表示樹,數組中的節點位置決定了它和其他節點的關系,比如堆。然而,圖并不像樹那樣擁有幾種固定的結構,因為圖的每個頂點可以與任意多個頂點連接。為了模擬這種自由形式的組織結構,需要用一種不同的方法表示邊,一般用兩種方式:鄰接矩陣和鄰接表。

    ??????? 鄰接矩陣是一個二維數組,里面的數據表示兩點間是否存在邊。如果圖有N個頂點,那么鄰接矩陣就是N*N的數組,如下表所示:1表示有邊,0表示沒有邊,也可以用true和false來表示。

    ?

    A

    B

    C

    A

    0

    1

    1

    B

    1

    0

    1

    C

    1

    1

    0

    ??????? 鄰接表是一個鏈表數組(或者鏈表的鏈表),每個單獨的鏈表表示了有哪些頂點與當前頂點鄰接,如下表所示:A鄰接頂點有B、C和D。

    頂點

    包含鄰接頂點的鏈表

    A

    B->C->D

    B

    A->D

    C

    A

    D

    A->B


    ??????? 下面討論下圖中的搜索。在圖中實現的基本操作之一就是搜索從一個定到可以到達其他哪些頂點,或者找所有當前頂點可到達的頂點。有兩種常用的方法可用來搜索圖:深度優先搜索(DFS)和廣度優先搜索(BFS),它們最終都會到達所有的連通頂點。深度優先搜索通過棧來實現,而廣度優先搜索通過隊列來實現。具體的見下面的程序:

    [java]?view plaincopy
  • public?class?Graph?{??
  • ????private?final?int?MAX_VERTS?=?20;??
  • ????private?Vertex?vertexArray[];???//存儲頂點的數組??
  • ????private?int?adjMat[][];?//存儲是否有邊界的矩陣數組,?0表示沒有邊界,1表示有邊界??
  • ????private?int?nVerts;?//頂點個數??
  • ????private?StackX?stack;???//深度搜索時用來臨時存儲的棧??
  • ????private?QueueX?queue;???//廣度搜索時用來臨時存儲的隊列??
  • ??
  • ????public?Graph()?{??
  • ????????vertexArray?=?new?Vertex[MAX_VERTS];??
  • ????????adjMat?=?new?int[MAX_VERTS][MAX_VERTS];??
  • ????????nVerts?=?0;??
  • ????????for(int?i?=?0;?i?<?MAX_VERTS;?i++)?{??
  • ????????????for(int?j?=?0;?j?<?MAX_VERTS;?j++)?{??
  • ????????????????adjMat[i][j]?=?0;??
  • ????????????}??
  • ????????}??
  • ????????stack?=?new?StackX();??
  • ????????queue?=?new?QueueX();??
  • ????}??
  • ??????
  • ????public?void?addVertex(char?lab)?{??
  • ????????vertexArray[nVerts++]?=?new?Vertex(lab);??
  • ????}??
  • ??????
  • ????public?void?addEdge(int?start,?int?end)?{??
  • ????????adjMat[start][end]?=?1;??
  • ????????adjMat[start][end]?=?1;??
  • ????}??
  • ??????
  • ????public?void?displayVertex(int?v)?{??
  • ????????System.out.print(vertexArray[v].label);??
  • ????}??
  • ??????
  • ????/*?
  • ?????*?深度優先搜索算法:做四件事?
  • ?????*?1.?用peek()方法檢查棧頂的頂點?
  • ?????*?2.?試圖找到這個頂點還未訪問的鄰節點?
  • ?????*?3.?如果沒有找到,出棧?
  • ?????*?4.?如果找到這樣的頂點,訪問這個頂點,并把它放入棧?
  • ?????*?深度優先算法類似于從樹的跟逐個沿不同路徑訪問到不同的葉節點?
  • ?????*/??
  • ????public?void?depthFirstSearch()?{??
  • ????????//begin?at?vertex?0??
  • ????????vertexArray[0].wasVisited?=?true;?//make?it??
  • ????????displayVertex(0);??
  • ????????stack.push(0);??
  • ??????????
  • ????????while(!stack.isEmpty())?{??
  • ????????????//get?an?unvisited?vertex?adjacent?to?stack?top??
  • ????????????int?v?=?getAdjUnvisitedVertex(stack.peek());??
  • ????????????if(v?==?-1)?{???//if?no?such?vertex??
  • ????????????????stack.pop();??
  • ????????????}??
  • ????????????else?{??//if?it?exists??
  • ????????????????vertexArray[v].wasVisited?=?true;??
  • ????????????????displayVertex(v);??
  • ????????????????stack.push(v);??
  • ????????????}??
  • ????????}??
  • ??????????
  • ????????//stack?is?empty,?so?we're?done??
  • ????????for(int?i?=?0;?i?<?nVerts;?i++)?{??
  • ????????????vertexArray[i].wasVisited?=?false;??
  • ????????}??
  • ????}??
  • ??????
  • ????//returns?an?unvisited?vertex?adj?to?v??
  • ????????public?int?getAdjUnvisitedVertex(int?v)?{??
  • ????????????for(int?i?=?0;?i?<?nVerts;?i++)?{??
  • ????????????????if(adjMat[v][i]?==?1?&&?vertexArray[i].wasVisited?==?false)?{//v和i之間有邊,且i沒被訪問過??
  • ????????????????????return?i;??
  • ????????????????}??
  • ????????????}??
  • ????????????return?-1;??
  • ????????}??
  • ??????
  • ????/*?
  • ?????*?廣度優先搜索算法:做四件事?
  • ?????*?1.?用remove()方法檢查棧頂的頂點?
  • ?????*?2.?試圖找到這個頂點還未訪問的鄰節點?
  • ?????*?3.?如果沒有找到,該頂點出列?
  • ?????*?4.?如果找到這樣的頂點,訪問這個頂點,并把它放入隊列中?
  • ?????*?深度優先算法中,好像表現的要盡快遠離起始點,在廣度優先算法中,要盡可能靠近起始點。?
  • ?????*?它首先訪問其實頂點的所有鄰節點,然后再訪問較遠的區域。這種搜索不能用棧,而要用隊列來實現。?
  • ?????*?廣度優先算法類似于從樹的跟逐層往下訪問直到底層?
  • ?????*/??
  • ????public?void?breadthFirstSearch()?{??
  • ????????vertexArray[0].wasVisited?=?true;??
  • ????????displayVertex(0);??
  • ????????queue.insert(0);??
  • ????????int?v2;??
  • ??????????
  • ????????while(!queue.isEmpty())?{??
  • ????????????int?v1?=?queue.remove();??
  • ????????????//until?it?has?no?unvisited?neighbors??
  • ????????????while((v2?=?getAdjUnvisitedVertex(v1))?!=?-1)?{??
  • ????????????????vertexArray[v2].wasVisited?=?true;??
  • ????????????????displayVertex(v2);??
  • ????????????????queue.insert(v2);??
  • ????????????}??
  • ????????}??
  • ??????????
  • ????????for(int?i?=?0;?i?<?nVerts;?i++)?{??
  • ????????????vertexArray[i].wasVisited?=?false;??
  • ????????}??
  • ????}??
  • }??
  • ??? 其中StackX和QueueX類的代碼如下:

    [java]?view plaincopy
  • public?class?QueueX?{??
  • ????private?final?int?SIZE?=?20;??
  • ????private?int[]?queArray;??
  • ????private?int?front;??
  • ????private?int?rear;??
  • ??????
  • ????public?QueueX()?{??
  • ????????queArray?=?new?int[SIZE];??
  • ????????front?=?0;???
  • ????????rear?=?-1;??
  • ????}??
  • ??????
  • ????public?void?insert(int?j)?{??
  • ????????if(rear?==?SIZE-1)?{??
  • ????????????rear?=?-1;??
  • ????????}??
  • ????????queArray[++rear]?=?j;??
  • ????}??
  • ??????
  • ????public?int?remove()?{??
  • ????????int?temp?=?queArray[front++];??
  • ????????if(front?==?SIZE)?{??
  • ????????????front?=?0;??
  • ????????}??
  • ????????return?temp;??
  • ????}??
  • ??????
  • ????public?boolean?isEmpty()?{??
  • ????????return?(rear+1?==?front?||?front+SIZE-1?==?rear);??
  • ????}??
  • }??

  • [java]?view plaincopy
  • public?class?StackX?{??
  • ????private?final?int?SIZE?=?20;??
  • ????private?int[]?stack;??
  • ????private?int?top;??
  • ??????
  • ????public?StackX()?{??
  • ????????stack?=?new?int[SIZE];??
  • ????????top?=?-1;??
  • ????}??
  • ??????
  • ????public?void?push(int?j)?{??
  • ????????stack[++top]?=?j;??
  • ????}??
  • ??????
  • ????public?int?pop()?{??
  • ????????return?stack[top--];??
  • ????}??
  • ??????
  • ????public?int?peek()?{??
  • ????????return?stack[top];??
  • ????}??
  • ??????
  • ????public?boolean?isEmpty()?{??
  • ????????return?(top?==?-1);??
  • ????}??
  • }??
  • ??????? 圖中還有個最小生成樹的概念,所謂最小生成樹,就是用最少的邊連接所有的頂點。對于給定的一組頂點,可能又很多種最小生成樹,但是最小生成樹邊E的數量總是比頂點V的數量小1,即E=V-1。尋找最小生成樹不需要關心邊的長度,并不需要找到一條最短路徑,而是要找最少數量的邊(最小路徑在帶權圖中討論)。

    ??????? 創建最小生成樹的算法與搜索算法幾乎是相同的,它同樣可以基于廣度優先搜索和深度優先搜索,這里使用深度優先搜索。在執行深度優先搜索的過程中,如果記錄走過的邊,就可以創建一棵最小生成樹,可能會感到有點奇怪。見下面的程序(是上面Graph類中的一個方法,加到Graph類中即可):

    [java]?view plaincopy
  • public?void?minSpanningTree()?{??
  • ????vertexArray[0].wasVisited?=?true;??
  • ????stack.push(0);??
  • ????while(!stack.isEmpty())?{??
  • ????????int?currentVertex?=?stack.peek();??
  • ????????int?v?=?getAdjUnvisitedVertex(currentVertex);??
  • ????????if(v?==?-1)?{??
  • ????????????stack.pop();??
  • ????????}??
  • ????????else?{??
  • ????????????vertexArray[v].wasVisited?=?true;??
  • ????????????stack.push(v);??
  • ????????????displayVertex(currentVertex);?//from?currentV??
  • ????????????displayVertex(v);?//to?v??
  • ????????????System.out.print("?");??
  • ????????}??
  • ????}??
  • ????//stack?is?empty,?so?we're?done??
  • ????for(int?j?=?0;?j?<?nVerts;?j++)?{??
  • ????????vertexArray[j].wasVisited?=?false;??
  • ????}??
  • }??
  • ??? 圖就探討到這里,如有錯誤,歡迎留言指正~+


    轉載:http://blog.csdn.net/eson_15/article/details/51113376

    總結

    以上是生活随笔為你收集整理的数据结构与算法09 之图的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。