普里姆算法–用邻接表的方法进行实现。邻接表的实现
实现步骤:
1.首先创建一个邻接表
2.使用一个空链表用于存信息
3.每次将顶点的信息进行入队
4.从链表中选取边最短的边
5.将节点的信息保存在数组miniPrime中,并将指向的顶点保存在Point数组
6.然后将链表中以这些Point的值为起点的或者重点的结点删除掉
7.直到将所有的顶点都选完
结构体定义
#include <stdio.h>
#include <malloc.h>
#define MAX_VERTEX_NUM 20
typedef enum
{
DN,//DiGraph 有向图
UN //UndiGraph 无向图
}GraphType;
typedef struct ArcNode
{
int startVex;//起始顶点
int adjVex; //指向顶点的位置
struct ArcNode *next;
int data;
}ArcNode;
typedef struct VNode
{
int vexNode;
ArcNode *firstNode;
}VNode;
typedef struct miniPrime
{
int startPoint;
int edgeData;
int endPoint;
}MiniPrime;
typedef struct ALGraph
{
VNode vertices[MAX_VERTEX_NUM];
int vexNum; //顶点个数。
GraphType kind; //图的种类标记
}ALGraph;
ALGraph *createGraph();
void printfGraph(ALGraph *alGraph );
void MiniSpanTree_Prime(ALGraph *alGraph ,int vertice);
void printfList(ArcNode *NodeList);
主要方法,每次从链表中选取值最小的边。
ArcNode *miniEdge(ArcNode *NodeList, ALGraph *alGraph,int startPoint,int Point[])
{
//printf("startPoint %d \n" ,startPoint);
ArcNode *vexNodeList = alGraph->vertices[startPoint].firstNode->next;
ArcNode *returnNode = (ArcNode *)malloc(sizeof(ArcNode));
int flag = 0;
ArcNode *List ;
returnNode->data = 1000;
//printfList(alGraph->vertices[startPoint].firstNode);
while(NULL != vexNodeList)
{//将节点加入链表
for(int i = 0; i < alGraph->vexNum ; i++)
{
//printf("point[%d]",Point[i]);
for(int j = i+1; j < alGraph->vexNum ; j++)
{
if(Point[i] == -1 || Point[j] ==-1)
{
break;
}
if((vexNodeList->adjVex == Point[j] && vexNodeList->startVex == Point[i])||
(vexNodeList->adjVex == Point[i] && vexNodeList->startVex == Point[j]))
{
if(vexNodeList->next != NULL)
{
//printf("list is not NULL\n");
vexNodeList = vexNodeList->next;
break;
}
else
{
//printf("list is NULL\n");
flag = 1;
break;
}
}
}
}
if(flag == 1)
{
break;
}
ArcNode *tmpNode = (ArcNode *)malloc(sizeof(ArcNode));
tmpNode->adjVex = vexNodeList->adjVex;
tmpNode->data = vexNodeList->data;
tmpNode->startVex = vexNodeList->startVex;
addarcNodetail(NodeList,tmpNode);
vexNodeList = vexNodeList->next;
}
//printfList(NodeList);
List = NodeList->next;
while( NULL != List)
{
if(returnNode->data > List->data)
{
//printf("returnNode->data %d List->data,%d\n", returnNode->data ,List->data);
returnNode->adjVex = List->adjVex;
returnNode->data = List->data;
returnNode->startVex = List->startVex;
}
List = List->next;
}
return returnNode;
}
所有函数
#include "Graph.h"
typedef struct Data
{
int a ;
int b ;
}Data;
Data dataArray[26]=
{
{1,6},{2,1},{3,5},{0,0},
{0,6},{2,5},{4,3},{0,0},
{0,1},{1,5},{3,5},{4,6},{5,4},{0,0},
{0,5},{2,5},{5,2},{0,0},
{1,3},{2,6},{5,6},{0,0},
{2,4},{3,2},{4,6},{0,0}
};
void addarcNodetail(ArcNode *list , ArcNode *tmpNode)
{
ArcNode *tmpList = list;
while(tmpList->next != NULL)
{
tmpList = tmpList->next ;
}
tmpList->next = tmpNode;
tmpNode->next = NULL;
return ;
}
ALGraph *createGraph()
{
ALGraph *alGraph = (ALGraph *) malloc(sizeof(ALGraph));
int vexNum , data , vexarc;
printf("please input vexNode num :");
scanf("%d",&vexNum);
alGraph->vexNum = vexNum;
int j = 0 ;
for(int i = 0 ; i < vexNum; i++)
{
alGraph->vertices[i].vexNode = i;
alGraph->vertices[i].firstNode =(ArcNode *)malloc(sizeof(ArcNode));
alGraph->vertices[i].firstNode->next = NULL;
alGraph->vertices[i].firstNode->adjVex = 0;
alGraph->vertices[i].firstNode->data = 0;
}
for(int i = 0 ; i < vexNum; j++)
{
ArcNode *tmpNode = (ArcNode *)malloc(sizeof(ArcNode));
tmpNode->adjVex = dataArray[j].a;
tmpNode->data = dataArray[j].b;
tmpNode->startVex = i;
if(dataArray[j].b > 0)
{//挂载节点
addarcNodetail(alGraph->vertices[i].firstNode,tmpNode);
}
else
{
i++;
}
}
return alGraph;
}
void printfGraph(ALGraph *alGraph)
{
for(int i = 0 ; i < alGraph->vexNum; i++)
{
ArcNode *tmpNode = (ArcNode *)malloc(sizeof(ArcNode));
printf("dingdianaaa %d->", i);
tmpNode = alGraph->vertices[i].firstNode->next;
while(tmpNode != NULL)
{
printf("tmpNode:%d->", tmpNode->adjVex);
tmpNode = tmpNode->next;
}
printf("NULL\n");
}
}
//如果图中存在顶点,则返回顶点的位置,如果没有则返回空
ArcNode *locate(ALGraph *alGraph,int vertice)
{
for(int i = 0; i < alGraph->vexNum; i++)
{
if(vertice = alGraph->vertices[i].vexNode)
{
return alGraph->vertices[i].firstNode;
}
}
return NULL ;
}
void printfList(ArcNode *NodeList)
{
ArcNode *tmpNode = (ArcNode *)malloc(sizeof(ArcNode));
tmpNode = NodeList->next;
printf("tmpList:");
while(tmpNode != NULL)
{
printf("startVex%d,adjVex%d,data%d ",tmpNode->startVex, tmpNode->adjVex, tmpNode->data);
tmpNode = tmpNode->next;
}
printf("\n");
}
void deleteNode(ArcNode *NodeList,int Point[],int num)
{
for(int i = 0; i < num ; i++)
{
//printf("point[%d]",Point[i]);
for(int j = i+1; j < num ; j++)
{
if(Point[i] == -1 || Point[j] ==-1)
{
break;
}
ArcNode *tmpNodeList = NodeList->next;
ArcNode *preNode = NodeList;
while(NULL != tmpNodeList)
{
// printf(" node(%d,%d,%d) ,Point[%d] (%d,%d)\n",tmpNodeList->startVex,tmpNodeList->adjVex,tmpNodeList->data, i,
// Point[i],Point[j]);
if((tmpNodeList->adjVex == Point[j] && tmpNodeList->startVex == Point[i])||
(tmpNodeList->adjVex == Point[i] && tmpNodeList->startVex == Point[j]))
{
//printf("delte node(%d,%d,%d)\n",tmpNodeList->startVex,tmpNodeList->adjVex,tmpNodeList->data);
preNode->next = tmpNodeList->next;
tmpNodeList = tmpNodeList->next;
}
else
{
tmpNodeList = tmpNodeList->next;
preNode = preNode->next;
}
}
}
}
}
ArcNode *miniEdge(ArcNode *NodeList, ALGraph *alGraph,int startPoint,int Point[])
{
//printf("startPoint %d \n" ,startPoint);
ArcNode *vexNodeList = alGraph->vertices[startPoint].firstNode->next;
ArcNode *returnNode = (ArcNode *)malloc(sizeof(ArcNode));
int flag = 0;
ArcNode *List ;
returnNode->data = 1000;
//printfList(alGraph->vertices[startPoint].firstNode);
while(NULL != vexNodeList)
{//将节点加入链表
for(int i = 0; i < alGraph->vexNum ; i++)
{
//printf("point[%d]",Point[i]);
for(int j = i+1; j < alGraph->vexNum ; j++)
{
if(Point[i] == -1 || Point[j] ==-1)
{
break;
}
if((vexNodeList->adjVex == Point[j] && vexNodeList->startVex == Point[i])||
(vexNodeList->adjVex == Point[i] && vexNodeList->startVex == Point[j]))
{
if(vexNodeList->next != NULL)
{
//printf("list is not NULL\n");
vexNodeList = vexNodeList->next;
break;
}
else
{
//printf("list is NULL\n");
flag = 1;
break;
}
}
}
}
if(flag == 1)
{
break;
}
ArcNode *tmpNode = (ArcNode *)malloc(sizeof(ArcNode));
tmpNode->adjVex = vexNodeList->adjVex;
tmpNode->data = vexNodeList->data;
tmpNode->startVex = vexNodeList->startVex;
addarcNodetail(NodeList,tmpNode);
vexNodeList = vexNodeList->next;
}
//printfList(NodeList);
List = NodeList->next;
while( NULL != List)
{
if(returnNode->data > List->data)
{
//printf("returnNode->data %d List->data,%d\n", returnNode->data ,List->data);
returnNode->adjVex = List->adjVex;
returnNode->data = List->data;
returnNode->startVex = List->startVex;
}
List = List->next;
}
return returnNode;
}
//vertice表示从那个顶点开始
void MiniSpanTree_Prime(ALGraph *alGraph ,int vertice)
{
ArcNode *startNode = locate(alGraph,vertice);
ArcNode *NodeList = (ArcNode *)malloc(sizeof(ArcNode));
NodeList->next = NULL;
MiniPrime miniPrime[alGraph->vexNum];
int Point[alGraph->vexNum];
ArcNode *miniNode;
int startPoint = vertice;
if(startNode == NULL )
{//没有这个顶点,
printf("this startNode is not exist \n");
return;
}
if(startNode->next == NULL )
{
printf("graph not have mini span tree");
}
for (int i = 1; i < alGraph->vexNum; i++)
{
miniPrime[i-1].startPoint = 0;
miniPrime[i-1].edgeData = 0;
miniPrime[i-1].endPoint = 0;
Point[i] = -1;
}
Point[0] = startPoint;
for (int i = 1; i < alGraph->vexNum; i++)
{
miniNode = miniEdge(NodeList,alGraph,startPoint,Point);
miniPrime[i-1].startPoint = miniNode->startVex;
miniPrime[i-1].edgeData = miniNode->data;
miniPrime[i-1].endPoint = miniNode->adjVex;
Point[i] = miniNode->adjVex;
startPoint = miniNode->adjVex;
deleteNode(NodeList,Point, alGraph->vexNum);
//printfList(NodeList);
printf("point(%d,%d,%d)\n", miniPrime[i-1].startPoint, miniPrime[i-1].endPoint,miniPrime[i-1].edgeData);
}
}
/*
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-09-16 22:03:45
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-11-05 13:04:55
* @FilePath: \bootstrap\main.c
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include <stdio.h>
#include <malloc.h>
#include <pthread.h>
#include <stdlib.h>
#include "Graph.h"
int main(void )
{
ALGraph *alGraph = createGraph();
//printfGraph(alGraph);
MiniSpanTree_Prime(alGraph,0);
printfGraph(alGraph);
return 0;
}
步骤图:
运行结果: