我之前也写过prim算法,现在再次来写,是因为自己觉得对于Prim算法的理解进行直观看待,这样好像更加理解充分些:
G=(V,E)-----V顶点集合,E为权值集合,
1)S={1}加入顶点集//例如第一个加入是1,i属于S,j属于V-S集合中找出C[i][j]最小的全职,此时将j加入S;
2)此时S集合中点数为2,j又在 V-S中取值。
3)循环找到最小的值,纪录点。知道找完为止。
4)这里要注意是找两个集合最近权值。
实现的代码:
#include <iostream>
using namespace std;
#define MaxLine 9999
typedef struct Node{
int node;
int data;
bool in;
struct Node*next;
}Node;
struct Queue{
Node *rear;
Node *front;
int size;
};
void IniQueue(Queue*q)
{
q->rear=q->front=(Node *)malloc(sizeof(Node));
q->size=0;
q->front->next=NULL;
}
void Enqueue(Queue *q,Node *p)
{
q->rear->next=p;
q->rear=p;
q->size++;
q->rear->next=NULL;
}
void PrimAlgorithm(Queue *q)
{
int n;
cout<<"the amount of node:";
cin>>n;
int **a=new int * [n+1];
for(int i=0;i<=n;i++)
a[i]=new int [n+1];
cout<<"specific data:(as -1 is on behalf of ending)"<<endl;
//初始化
for(int i=1;i<n+1;i++)
{
for(int j=1;j<n+1;j++)
a[i][j]=MaxLine;
}
int i,j,k;
//录入值:
while(cin>>i>>j>>k)
{
if(i>n||j>n)
break;
if((i>0&&i<=n)&&(j>0&&j<=n))
{
a[i][j]=k;
a[j][i]=k;
}
if(i==-1||j==-1)
break;
}
int start;
cout<<"the starting node:";
cin>>start;
Node *p=(Node *)malloc(sizeof(Node));
p->node=start;
p->data=MaxLine;
p->in=false;
bool arr[n+1];
for(int i=1;i<=n;i++)
arr[i]=false;
arr[start]=true;
Enqueue(q, p);
while(q->size!=n)
{
int value=MaxLine;
int load;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(arr[i]==true&&arr[j]==false)
{
if(a[i][j]!=MaxLine&&value>a[i][j])
{
value=a[i][j];
load=j;
}
}
}
//找出两集合中最小的路径和点
arr[load]=true;//纪录为做过了
Node *l=(Node*)malloc(sizeof(Node));
l->data=value;
l->node=load;
l->in=false;
Enqueue(q, l);//入队
}
}
//打印
void show(Queue s)
{
Node *p=s.front->next;
Node *d=s.front->next;
while(p!=s.rear->next)
{
cout<<" "<<p->node;
p=p->next;
}
cout<<endl;
while(d!=s.rear->next){
if(d->data==MaxLine)
cout<<"not";
else
cout<<" "<<d->data;
d=d->next;
}
cout<<endl;
}
--算法复杂度高,其实也便于理解起形成过程