最小生成树Prim算法实现(采用邻接表存储)C++实现

本文详细介绍了最小生成树算法的实现过程,包括邻接表存储方式,并通过实例展示了如何构建最小生成树,以及计算其权值总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  

// Prim算法实现(采用邻接表存储).cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdafx.h"
#include<iostream>
#define MAX 100
#define Infinity 65535
typedef  int WeiType;
using namespace std;

struct edgeNode
{
 int no; //边端的序号
 char info; //边端的名称
 WeiType weight; //边的权值
 struct edgeNode * next; //下一个
};

struct vexNode
{
 char info;  //节点名称
 struct edgeNode *link; //与之相连的端点
};

//存储节点信息
vexNode adjlist[MAX];
//访问标志
bool visited[MAX];
//lowcost[j]存储从开始节点到节点j的最小花费
WeiType lowcost[MAX];
//parent[j]表示节点j的前驱节点
int parent[MAX];

//建立邻接表存储
void createGraph(vexNode *adjlist,const int n,const int e,const int v0)
{
 
 int i;
 for(i=1;i<=n;i++)
 {
  cout<<"请输入节点"<<i<<"的名称:";
  cin>>adjlist[i].info;
  adjlist[i].link = NULL;
  //初始化
  visited[i] = false;
  lowcost[i] = Infinity;
  parent[i] = v0;
 }
 edgeNode *p1,*p2;
   int v1,v2;
   WeiType weight;
 for(i=1;i<=e;i++)
 {
  cout<<"请输入边"<<i<<"的二端的节点序号:";
  cin>>v1>>v2;
  cout<<"此边的权值:";
  cin>>weight;
  p1 = (edgeNode*)malloc(sizeof(edgeNode));
  p2 = (edgeNode*)malloc(sizeof(edgeNode));
  p1->no = v1;
  p1->weight = weight;
  p1->info = adjlist[v1].info;
  p1->next = adjlist[v2].link;
  adjlist[v2].link = p1;
  p2->no = v2;
  p2->weight = weight;
  p2->info = adjlist[v2].info;
  p2->next = adjlist[v1].link;
  adjlist[v1].link = p2;
 }
}


int _tmain(int argc, _TCHAR* argv[])
{
 int cases;
 cout<<"请输入案例的个数:";
 cin>>cases;
 while(cases--)
 {
  int n,e;
  cout<<"请输入节点数:";
  cin>>n;
  cout<<"请输入边数:";
  cin>>e;
  cout<<"请输入从哪一个节点开始:";
  int v;
  cin>>v;
  int i,j;
  //最小生成树的权值总和
  WeiType sum = 0;
  createGraph(adjlist,n,e,v);
  edgeNode *p,*q;
  p = adjlist[v].link;
  visited[v] = true;
  while(p!=NULL)
  {
   lowcost[p->no] = p->weight;
   p = p->next;
  }
  WeiType minCost;
  for(i=1;i<n;i++)
  {
   minCost = Infinity;
   int k;
   for(j=1;j<=n;j++)
   {
    if(minCost>lowcost[j]&&!visited[j])
    {
     minCost = lowcost[j];
     k = j;
    }
   }
   sum += minCost;
   visited[k] = true;
   q = adjlist[k].link;
   while(q != NULL)
   {
    if(!visited[q->no]&&q->weight<lowcost[q->no])
    {
     lowcost[q->no] = q->weight;
     parent[q->no] = k;
    }
    q = q->next;
   }
  }
  cout<<"最小生成树的边集为:"<<endl;
  for(i=1;i<=n;i++)
   if(i!=v)
    cout<<"("<<adjlist[parent[i]].info<<","<<adjlist[i].info<<")"<<" ";
  cout<<endl;
  cout<<"最小生成树的权值为:"<<sum<<endl;
 }
 system("pause");
 return 0;
}

-----------------------------------------------------程序测试--------------------------------------------------

                             

请输入案例的个数:1
请输入节点数:9
请输入边数:14
请输入从哪一个节点开始:2
请输入节点1的名称:a
请输入节点2的名称:b
请输入节点3的名称:c
请输入节点4的名称:d
请输入节点5的名称:e
请输入节点6的名称:f
请输入节点7的名称:g
请输入节点8的名称:h
请输入节点9的名称:i
请输入边1的二端的节点序号:1 2
此边的权值:4
请输入边2的二端的节点序号:1 8
此边的权值:8
请输入边3的二端的节点序号:2 3
此边的权值:8
请输入边4的二端的节点序号:2 8
此边的权值:11
请输入边5的二端的节点序号:3 4
此边的权值:7
请输入边6的二端的节点序号:3 6
此边的权值:4
请输入边7的二端的节点序号:3 9
此边的权值:2
请输入边8的二端的节点序号:4 5
此边的权值:9
请输入边9的二端的节点序号:4 6
此边的权值:14
请输入边10的二端的节点序号:5 6
此边的权值:10
请输入边11的二端的节点序号:6 7
此边的权值:2
请输入边12的二端的节点序号:7 8
此边的权值:1
请输入边13的二端的节点序号:7 9
此边的权值:6
请输入边14的二端的节点序号:8 9
此边的权值:7
最小生成树的边集为:
(b,a) (b,c) (c,d) (d,e) (c,f) (f,g) (g,h) (c,i)
最小生成树的权值为:37
请按任意键继续. . .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值