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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构题:克鲁斯卡尔(Kruscal)算法求最小生成树

發布時間:2024/2/28 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构题:克鲁斯卡尔(Kruscal)算法求最小生成树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、目的與要求
    • 設計目的
    • 設計要求
  • 二、原理及方案
    • 1.克魯斯卡爾(Kruskal)算法
    • 2.方案思路
  • 三、設計過程
  • 四、設計結果
  • 五、例題測試
  • 總結
  • 結語


前言

問題描述:用克魯斯卡爾算法求無向網圖的最小生成樹。本文編程軟件是Visual Studio 2019,使用的是C語言進行課程設計。


提示:以下是本篇文章正文內容,下面案例可供參考。

一、目的與要求

設計目的

  • 該課題的源碼必須能夠調試成功;
  • 提供一個main函數完成的程序源碼版本。基本數據結構有詳細說明,每個功能函數有詳細說明;
  • 全文關鍵代碼須加上注釋。
  • 設計要求

  • 生成一個無向網圖;
  • 要求采用鄰接矩陣或鏈接表存儲來完成;
  • 最后打印輸出最小生成樹;
  • 每一個函數要有必要的注釋,在課程設計中有流程圖。
  • 二、原理及方案

    1.克魯斯卡爾(Kruskal)算法

    克魯斯卡爾算法的思想是:假設G=(V,E)是一個具有n給頂點的連通網,T=(U,TE)是G的最小生成樹。U的初值等于V,即擁有G中的全部頂點。算法開始時,TE的初值為空值。將圖G中的邊按權值從小到大的順序依次選取,若選取的邊使生成樹T不形成回路,則把它并入TE中,保留作為T的一條邊;若選取的邊使生成樹T形成回路,則將其舍棄,如此進行下去,直到TE中包含n-1條邊為止,此時的T即為最小生成樹。
    🎈這里我們通過一個例子了解如何對一個無向帶權圖采用克魯斯卡爾算法求其最小生成樹:


    例,對于下圖所示的無向帶權圖,采用克魯斯卡爾算法求最小生成樹的過程為:

    通過該圖,可知其中的邊按權值由小到大的順序是:
    從頂點5開始,連接5和4,權值為1

    再連接3,4,權值為2,此時選取的邊使生成樹T形成回路,舍棄;從另一邊連接5,0,權值為3;再連接0,2,權值為4,形成回路舍棄;連接5,1,權值為5,如下圖,即得到最小生成樹:

    步驟生成樹中各頂點集合生成樹的邊生成樹的權值
    初始狀態{0},{1},{2},{3},{4},{5}
    1{0},{1},{2},{3},{4,5}(4,5)1
    2{0},{1},{2},{3,4,5}(3,4)2
    3{1},{2},{0,3,4,5}(0,5)3
    4{1},{2,0,3,4,5}(0,2)4
    5{1,2,0,3,4,5}(1,5)5

    實現該算法需要設一個邊集合數組E,其中包括邊的起始點u,終止點v和這條邊的權值w。首先編寫函數CreateEdge循環建立一個邊集合E,并返回邊的數目n。因為克魯斯卡爾算法要求邊集必須是按從小到大的順序排好,所以編寫函數seeks實現對數組E進行排序的功能,函數sort排序的結果是E中各邊按從小到大排好序。
    克魯斯卡爾算法的編程思路是首先要用到輔助數組set,用來存放各頂點所在的最小生成樹頂點集合,然后從邊集E中順序取出各條邊,判斷該邊的兩個頂點是否在同一集合中(需要編寫一個判斷頂點所在集合的函數seeks),若不在同一集合,則該邊為最小生成樹的一條邊,輸出該條邊的頂點序列和權值,并在set數組中將頂點v2加到頂點v1集合中,重復以上操作直到所有頂點都在一個集合中結束。

    2.方案思路

    Prim算法是找點,而我們所用的Kruscal算法則是從邊出發。
    具體思路:
    1.把所有的邊和這條邊代表的權值用一個數組存儲起來,并按權值大小給數組排序(升序)。
    2.按順序從數組中拿出一條邊,檢查這條邊是否與到目前為止形成的樹構成環,如果形成了環,就丟棄它;如果沒有,就把這條邊加入樹中。
    3.重復步驟2,直到樹中有 n-1 條邊為止。

    三、設計過程

    程序中無向網采用鄰接矩陣存儲,c程序如下:

    //克魯斯卡爾(Kruscal)算法求最小生成樹 #include <stdio.h> #define MAX 100 //定義最大頂點數 typedef struct //建立一個邊集合數組,其中包括邊的起始點、終止點以及這條邊的權值 {int u; //一條邊的起始頂點int v; //一條邊的終止頂點int w; //邊的權值(權重) }Edge; //邊的類型定義 Edge E[MAX]; //定義一個全局數組E,用于存儲圖的各條邊(創建邊的數組) //創建一個無向網圖 int CreateEdge() {int i;int anum;printf("\n輸入無向網的邊數:");scanf_s("%d", &anum);for (i = 0; i < anum; ++i){printf("\n輸入第%d條邊的起始頂點、終止頂點以及該邊的權值(v1、v2、w):\n",i+1);scanf_s("%d %d %d", &E[i].u, &E[i].v, &E[i].w);}return anum; }//對邊表進行從小到大排序算法 void sort(int n) {int i, j;Edge t;for (i = 0; i < n-1; i++)for(j=i+1;j<n;j++)if(E[i].w>E[j].w){t = E[i];E[i] = E[j];E[j] = t;} }//在邊表中查看頂點v在哪個連通集合中 int seeks(int set[], int v) {int i = v;while (set[i] > 0)i = set[i];return(i); }//克魯斯卡爾算法的核心環節 void Kruskal(Edge E[], int n) //算法核心環節 {int set[MAX]; //創建狀態臨時數組(輔助標志數組)int v1, v2, i; //數組中的下標的臨時變量for (i = 0; i < MAX; i++)set[i] = 0; //給set數組中的每個元素賦予初值i = 0; //i表示特獲取的生成樹種的邊數,初值為1while(i<n) //按邊權遞增順序,逐邊檢查該邊是否應加入到生成樹中 {v1 = seeks(set, E[i].u); //確定頂點v所在的連通集v2 = seeks(set, E[i].v);if (v1!=v2) //當v1,v2不在同一頂點集合,確定該邊應當選入生成樹{printf("(%d,%d) %d\n",E[i].u,E[i].v,E[i].w);set[v1]=v2; //將v2加入到v1的集合中}i++;} }void main() {int n;n=CreateEdge(); //調用生成邊表函數if(n>0) //判斷輸入的n值是否合法(n>0){sort(n); //對邊表集合進行排序printf("\n最小生成樹為( (頂點,頂點) 權值 ):\n");}elseprintf("\n輸入邊數錯誤,請重新輸入!\n");Kruskal(E,n); //調用克魯斯卡爾算法求最小生成樹 }

    四、設計結果

    五、例題測試

    剛剛更新,我們通過一道題由以上代碼可解決,直接上張圖:

    總結

    以上就是今天要講的內容,本文利用克魯斯卡爾(Kruscal)算法求最小生成樹中(無向網采用鄰接矩陣存儲),最后我們要知道克魯斯卡爾算法的時間復雜度是主要由排序方法決定的,其排序方法只與網中邊的條數有關,而與網中頂點的個數無關,當使用時間復雜度為O(elog2e)的排序方法時,克魯斯卡爾算法的時間復雜度即為O(log2e),因此當網的頂點個數較多、而邊的條數較少時,使用克魯斯卡爾算法構造最小生成樹效果較好。

    結語

    本文參考《數據結構》–上海交大
    如有錯誤,歡迎指正!

    總結

    以上是生活随笔為你收集整理的数据结构题:克鲁斯卡尔(Kruscal)算法求最小生成树的全部內容,希望文章能夠幫你解決所遇到的問題。

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