當前位置:首頁 > 企業軟件 > 其他 > 正文

數據結構:最小生成樹--Prim算法

最小生成樹:Prim算法 最小生成樹 ? ? 給定一無向帶權圖,頂點數是n,要使圖連通只需n-1條邊,若這n-1條邊的權值和最小,則稱有這n個頂點和n-1條邊構最小生成樹:Prim算法 最小生成樹 ? ? 給定一無向帶權圖,頂點數是n,要使圖連通只需n-1條邊,若這n-1條邊的權值和最小,則稱有這n個頂點和n-1條邊構成了圖的最小生成樹(minimum-cost spanning tree)。 Prim算法 ? ? Prim算法是解決最小生成樹的常用算法。它采取貪心策略,從指定的頂點開始尋找最小權值的鄰接點。圖G=<V,E>,初始時S={V0},把與V0相鄰接,且邊的權值最小的頂點加入到S。不斷地把S中的頂點與V-S中頂點的最小權值邊加入,直到所有頂點都已加入到S中。 算法說明 為了方便尋找最小權值的邊,構建一最近邊結構體CloseEdge: //最近邊
typedef struct closeedge_tag
{
int adjvex; //鄰接點
int weight; //權值
}CloseEdge;創建一數組CloseEdge closeedge[n];頂點u屬于S,頂點v屬于V-S,則closeedge[v].weight=min{weight(u,v)};closeedge[v].adjvex=u;另外設置一bool型的數組add,標記頂點i是否已加入S。結合closeedge和add即可得到當前最小權值邊。每當有新的節點加入S時,則需更新closeedge。具體細節看代碼。 實例 從V0開始 代碼 類定義 #include<iostream> 
#include<iomanip>
#include<stack>
using namespace std;
#define MAXWEIGHT 100
//邊
typedef struct edge_tag
{
int tail;
int head;
}Edge;
//最近邊
typedef struct closeedge_tag
{
int adjvex; //鄰接點
int weight; //權值
}CloseEdge;
class Graph
{
private:
//頂點數 
int numV;
//邊數 
int numE;
//鄰接矩陣 
int **matrix;
public:
Graph(int numV);
//建圖 
void createGraph(int numE);
//析構方法 
~Graph();
//Prim算法
void Prim(int);
int minEdgeVex(CloseEdge*, bool*);
void updateCloseEdge(CloseEdge*, bool*, int);
//打印鄰接矩陣 
void printAdjacentMatrix();
//檢查輸入 
bool check(int, int, int);
}; 類實現 //構造函數,指定頂點數目
Graph::Graph(int numV)
{
//對輸入的頂點數進行檢測
while (numV <= 0)
{
cout << "頂點數有誤!重新輸入 ";
cin >> numV;
}
this->numV = numV;
//構建鄰接矩陣,并初始化
matrix = new int*[numV];
int i, j;
for (i = 0; i < numV; i++)
matrix[i] = new int[numV];
for (i = 0; i < numV; i++)
for (j = 0; j < numV; j++)
{
if (i == j)
matrix[i][i] = 0;
else
matrix[i][j] = MAXWEIGHT;
}
}
void Graph::createGraph(int numE)
{
/*
對輸入的邊數做檢測
一個numV個頂點的有向圖,最多有numV*(numV - 1)條邊
*/
while (numE < 0 || numE > numV*(numV - 1))
{
cout << "邊數有問題!重新輸入 ";
cin >> numE;
}
this->numE = numE;
int tail, head, weight, i;
i = 0;
cout << "輸入每條邊的起點(弧尾)、終點(弧頭)和權值" << endl;
while (i < numE)
{
cin >> tail >> head >> weight;
while (!check(tail, head, weight))
{
cout << "輸入的邊不正確!請重新輸入 " << endl;
cin >> tail >> head >> weight;
}
//Prim算法主要針對的是無向圖
matrix[tail][head] = weight;
matrix[head][tail] = weight;
i++;
}
}
Graph::~Graph()
{
int i;
for (i = 0; i < numV; i++)
delete[] matrix[i];
delete[]matrix;
}
/*
Prim算法
求最小生成樹
*/
void Graph::Prim(int vertex)
{
//有numV個頂點的圖的最小生成樹有numV-1條邊
Edge *edges = new Edge[numV - 1];
//標記頂點是否加入
bool *add = new bool[numV];
memset(add, 0, numV);
//先把vertex加入
add[vertex] = true;
//最近邊
CloseEdge *closeedge = new CloseEdge[numV];
int i;
//初始化最近邊
for (i = 0; i < numV; i++)
{
closeedge[i].weight = matrix[vertex][i];
if (!add[i] && matrix[vertex][i] > 0 && matrix[vertex][i] < MAXWEIGHT)
closeedge[i].adjvex = vertex;
}
int v, count = 0;
while (count < numV - 1)
{
//獲取最近邊的鄰接點
v = minEdgeVex(closeedge, add);
add[v] = true;
//把最小權值邊依次加入數組edges
edges[count].tail = closeedge[v].adjvex;
edges[count].head = v;
//更新最近邊
updateCloseEdge(closeedge, add, v);
count++;
}
cout << "從頂點 " << vertex << " 開始,最小生成樹的邊是" << endl;
for (i = 0; i < count; i++)
cout << edges[i].tail << "---" << edges[i].head << endl;
//釋放空間
delete[]edges;
delete[]add;
delete[]closeedge;
}
//從closeedge中尋找最小邊的鄰接頂點
int Graph::minEdgeVex(CloseEdge *closeedge, bool *add)
{
int i, v, w; 
v = 0;
w = MAXWEIGHT;
for (i = 0; i < numV ; i++)
if (!add[i] && closeedge[i].weight < w)
{
w = closeedge[i].weight;
v = i;
}
return v;
}
//頂點v的加入后,需要更新最近邊
void Graph::updateCloseEdge(CloseEdge* closeedge, bool *add, int v)
{
int i;
for (i = 0; i < numV; i++)
if (!add[i] && matrix[v][i] < closeedge[i].weight)
{
closeedge[i].adjvex = v;
closeedge[i].weight = matrix[v][i];
}
}
//打印鄰接矩陣 
void Graph::printAdjacentMatrix()
{
int i, j;
cout.setf(ios::left);
cout << setw(7) << " ";
for (i = 0; i < numV; i++)
cout << setw(7) << i;
cout << endl;
for (i = 0; i < numV; i++)
{
cout << setw(7) << i;
for (j = 0; j < numV; j++)
cout << setw(7) << matrix[i][j];
cout << endl;
}
}
bool Graph::check(int tail, int head, int weight)
{
if ((tail == head) || tail < 0 || tail >= numV 
|| head < 0 || head >= numV
|| weight <= 0 || weight >= MAXWEIGHT)
return false;
return true;
}主函數 int main()
{
cout << "******Prim***by David***" << endl;
int numV, numE;
cout << "建圖..." << endl;
cout << "輸入頂點數 ";
cin >> numV;
Graph graph(numV);
cout << "輸入邊數 ";
cin >> numE;
graph.createGraph(numE);
cout << endl << "Prim..." << endl;
/*
由于輸出結果太長,不利于截圖,故只打印一半的節點
要想獲得從所有節點開始的最小生成樹,修改i的變化范圍即可
*/
for (int i = 0; i < numV / 2; i++)
graph.Prim(i);
system("pause");
return 0;
}運行 完整代碼下載:Prim算法 轉載請注明出處,本文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/38377091 若有所幫助,頂一個哦! 專欄目錄: 數據結構與算法目錄? c指針
友情鏈接
異常 - Exception - Copyright © 2014 - 2014 - 開發異常網 - 鄂ICP備14001750號 - 網站地圖
乐客彩彩票 东丰县 | 澄江县 | 辉南县 | 绩溪县 | 赤壁市 | 嘉黎县 | 昌江 | 余姚市 | 葫芦岛市 | 巴林左旗 | 静海县 | 肇州县 | 板桥市 | 于田县 | 商河县 | 平武县 | 兰州市 | 洛阳市 | 蓝田县 | 乌兰县 | 乌鲁木齐市 | 郎溪县 | 玉山县 | 西充县 | 巫溪县 | 岚皋县 | 武鸣县 | 中江县 | 青岛市 | 繁峙县 | 天水市 | 泌阳县 | 陇西县 | 井陉县 | 长兴县 | 鄄城县 | 临夏县 | 广平县 | 西林县 | 丹江口市 | 文成县 | 天台县 | 东乌珠穆沁旗 | 平罗县 | 桓台县 | 和龙市 | 西和县 | 二连浩特市 | 广西 | 花莲县 | 五华县 | 米泉市 | 望都县 | 孝昌县 | 兴安县 | 广汉市 | 嘉义县 | 海原县 | 武功县 | 永川市 | 平潭县 | 和平区 | 新宾 | 通化县 | 巴楚县 | 应城市 | 西青区 | 封丘县 | 大竹县 | 时尚 | 额济纳旗 | 沁阳市 | 桂林市 | 南郑县 | 剑川县 | 呈贡县 | 聊城市 | 南汇区 | 漾濞 | 垣曲县 | 禄丰县 | 龙岩市 | 台东市 | 尤溪县 | 临武县 | 广平县 | 大丰市 | 惠东县 | 金阳县 | 莫力 | 马尔康县 | 增城市 | 中江县 | 安乡县 | 郁南县 | 长宁区 | 彭阳县 | 湘阴县 | 垦利县 | 阿图什市 | 盘锦市 | 呼伦贝尔市 | 康马县 | 克什克腾旗 | 普定县 | 疏勒县 | 迁安市 | 赞皇县 | 滦南县 | 浦江县 | 静安区 | 疏勒县 | 德州市 | 康平县 | 大竹县 | 龙泉市 | 屏山县 | 阿勒泰市 | 神池县 | 安阳县 | 大竹县 | 吉木乃县 | 无极县 | 敖汉旗 | 成安县 | 康乐县 | 旺苍县 | 南阳市 | 苏尼特右旗 | 兴和县 | 巴青县 | 建湖县 | 措勤县 | 桦南县 | 琼海市 | 镇宁 | 鄯善县 | 南昌市 | 兴义市 | 若羌县 | 连南 | 广宁县 | 贡觉县 | 留坝县 | 盐源县 | 衡山县 | 陆丰市 | 邳州市 | 甘德县 | 夏津县 | 固阳县 | 汉源县 | 唐海县 | 扶沟县 | 临泽县 | 法库县 | 平塘县 | 甘孜 | 大邑县 | 南澳县 | 琼结县 | 平果县 | 普宁市 | 台前县 | 宁武县 | 平武县 | 大田县 | 那曲县 | 黎川县 | 顺平县 | 北流市 | 静安区 | 平远县 | 张掖市 | 盐池县 | 法库县 | 灌南县 | 仙居县 | 蓬莱市 | 灵山县 | 高青县 | 常熟市 | 定日县 | 竹山县 | 高碑店市 | 永宁县 | 孟津县 | 黄骅市 | 柞水县 | 泰宁县 | 郁南县 | 新龙县 | 巍山 | 禄劝 | 绥德县 | 资讯 | 焦作市 | 莆田市 | 无锡市 | 陵川县 | 盘山县 | 东乡族自治县 | 孟连 | 丰县 | 马龙县 | 黄梅县 | 山丹县 | 正镶白旗 | 汨罗市 | 留坝县 | 大连市 | 乐清市 | 民权县 | 柳州市 | 盐亭县 | 固始县 | 凤凰县 | 江永县 | 克山县 | 青海省 | 竹山县 | 蒙城县 | 台南县 | 东宁县 | 息烽县 | 富裕县 | 通山县 | 永福县 | 靖州 | 东光县 | 顺昌县 | 亳州市 | 灌云县 | 和林格尔县 | 龙井市 | 四平市 | 敖汉旗 | 台南市 | 德庆县 | 阿瓦提县 | 邵阳县 | 洮南市 | 留坝县 | 辉南县 | 荔浦县 | 碌曲县 | 奈曼旗 | 深州市 | 视频 | 晋宁县 | 溆浦县 |