資料結構課設 7最小生成樹問題

2022-05-31 10:24:09 字數 4279 閱讀 9340

14、最小生成樹問題(**)

【問題描述】

若要在n

個城市之間建設通訊網路,只需要假設

n-1條線路即可。如何以最低的經濟代價建設這個通訊網,是乙個網的最小生成樹問題。

【系統要求】

1.利用克魯斯卡爾演算法求網的最小生成樹。

2.利用普里姆演算法求網的最小生成樹。

3.要求輸出各條邊及它們的權值。

【測試資料】

由學生任意指定,但報告上要求寫出多批資料測試結果。

【實現提示】

通訊線路一旦建成,必然是雙向的。因此,構造最小生成樹的網一定是無向網。設圖的頂點數不超過

30個,並為簡單起見,網中邊的權值設成小於

100的整數,可利用

c語言提供的隨機函式產生。

圖的儲存結構的選取應和所作操作相適應。為了便於選擇權值最小的邊,此題的儲存結構既不選用鄰接矩陣的陣列表示法,也不選用鄰接表,而是以儲存邊(帶權)的陣列表示圖。

【選作內容】

利用堆排序實現選擇權值最小的邊。

一、演算法設計

1.隨機生成圖我利用的是c語言中的random()和rang()函式,採取系統時間為隨機種子,再生成隨機數,保證每次生成的圖不相同。因為我所構造的圖的儲存是30*30的鄰接矩陣,在構造圖的過程中利用隨機函式先產生1~30之間的30個隨機數。然後從第乙個數開始,判斷之後的數是否與它相同,如果不同就再利用隨機函式生成乙個1~90之間的隨機數作為邊的權值。而第乙個數作為邊的始點,第二個數作為邊的終點,儲存進鄰接矩陣。當然這不能夠保證生成的圖是聯通的。所以對鄰接矩陣進行一次遍歷。如果該行所有數全部為0,就產生乙個與此時行數不同的1~30之間的數,乙個1~90之間的數,重新進行儲存,保證生成的圖肯定是乙個連通圖。然後在進行一趟遍歷,統計總共有的邊數,同時遍歷的過程檢查是否為無向圖,如果不是,行列互換位置賦值,保證是無向圖。邊集陣列構造好之後需要按照權重大小進行排序,這裡我利用的是快速排序,與題目的中的堆排序有些出入。邊集陣列是為克魯斯卡爾演算法做準備的,每次加入一條邊檢查是否屬於構成了環,所以還需要利用乙個輔助陣列來標記,記為father陣列,類似於並查集中的思想。對於普里姆演算法,需要將原來的鄰接矩陣重新修整,所有為0的地方全部變為inf(即假定的無窮大數值)。在最後計算總花費的時候再利用原來的鄰接矩陣計算。

各個函式之間的呼叫關係如下圖所示:

main()

mainjiemian()

creatgraph()

prim()

quicksort()

kruskal()

jieshu()

partion()

find()

mainjiemian()

2.本程式中包含8個模組

(1)主函式:int main();

(2)結束函式:void jieshu();

(3)主介面函式:void mainjiemian();

(4)克魯斯卡爾演算法:void kruskal(edgetype edge[max_edge_num]);

(5)快速排序函式:

void quicksort(edgetype edge[max_edge_num],int low, int high)

int partion(edgetype edge[max_edge_num], intlow, int high)

(6)尋找根結點:int find(intfather[maxvertexnum], int v);

(7)普里姆演算法:void prim(graph*g,int w[100], int fa, int n);

(8)隨機生成圖:voidcreatgraph(graph *g);

3.元素型別、結點型別和指標型別

#define inf 65535

#define maxvertexnum 35        /*最大頂點數為30*/

#define max_edge_num 1000

typedef int vertextype;          /*頂點型別設定為字元型*/

typedef int edgetype;            /*邊的權值設為整型*/

typedef struct

graph; /*graph是以鄰接矩陣儲存的圖型別*/

typedef struct

edgetype;

二、實驗測試

圖的生成並不是固定的隨機方法,可以保證前後無關聯性

源**:

#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

int edgenum = 0;

#define inf 65535

#define maxvertexnum 35 /*最大頂點數為30*/

#define max_edge_num 1000

typedef int vertextype; /*頂點型別設定為字元型*/

typedef int edgetype; /*邊的權值設為整型*/

typedef struct

graph; /*graph是以鄰接矩陣儲存的圖型別*/

typedef struct

edgetype;

edgetype edge[max_edge_num]; /*定義邊集陣列*/

void creatgraph(graph *g) /*建立無向圖g的鄰接矩陣儲存*/

} for (i = 0; i < 30; i++)

ans[i] = rand() % 30 + 1; /*產生隨機的城市*/

for (i = 0; i < 30; i++) /*隨機生成權值,構造鄰接矩陣*/

}} for (i = 1; i <= g->n; i++)/*完善整個圖,使之必定為連通圖*/

}if (!flag)

int v = rand() % 90 + 1;

g->edges[i][t] = v;

g->edges[t][i] = v;

} }for (i = 1; i <= 30; i++) }

i = 1;

while (i <= edgenum)

}} }

for (i = 1; i <= g->n; i++)

printf("\n"); }}

void prim(graph *g,int w[100], int fa, int n)

for (i = 2; i <= n; i++) }

printf("最小生成樹如下:\n");

int cost = 0;

for (int i = 2; i <= 30; i++) /*列印結果*/

printf("最少花費成本為:%d\n", cost);

}int find(int father[maxvertexnum], int v)/*尋找頂點v所在樹的根節點*/

return v;

}int partion(edgetype edge[max_edge_num], int low, int high)/*對邊集陣列進行排序*/

case'2':

}prim(g, w, fa, g->n);

system("pause");

system("cls");

mainjiemian();

break;

} case'3':

case'4':

default:

}} return 0;

}

資料結構 最小生成樹問題

假設n 是乙個連通網,u是頂點集v的乙個非空子集,若 u,v 是一條具有最小權值的邊,其中u u,v v u,則比存在一棵包含邊 u,v 的最小生成樹 假設集合u裡面存放的是已經在最小生成樹中的頂點,集合te存放的是最小生成樹的邊,演算法從u 開始,在所有u u,v v u的所有邊 u,v 中選一條...

資料結構 最小生成樹

生成樹 乙個連通圖的最小連通子圖稱作該圖的生成樹。有n個結點的連通圖的生成樹有n個結點和n 1條邊。乙個有n個結點的連通圖的生成樹是原圖的極小連通子圖,它包含原圖中的所有n個結點,並且有保持圖連通的最少的邊。由生成樹的定義可知 若在生成樹中刪除一條邊,就會使該生成樹因變成非連通圖而不再滿足生成樹的定...

資料結構(最小生成樹)

對於乙個無相連通網,他的所有生成樹中必有一棵邊的權值總和最小的生成樹,稱之為最小代價生成樹,簡稱最小生成樹。最小生成樹必須滿足三個條件 1 構造的最小生成樹必須包括n個頂點 2 構造的最小生成樹有且僅有n 1條邊 3 構造的最小生成樹中不存在迴路。普利姆演算法 prim 假設g v,e 為一無向連通...