一、prim算法实现

二、最短路径

三、图的邻接表存储


一、prim算法实现

#include<stdio.h>
#include<stdlib.h>

#define VEXNUM 6//顶点数
#define ARCNUM 10//边数
#define MAX_VAL 100//先定义最大权值;

int s_set[VEXNUM+1], s_count;//标记被加入最小生成树的点与数量
int vs_count;//标记原来树中节点的数目;

struct Graph{
	int vexs[VEXNUM+1];//顶点数组;
    int a[VEXNUM+1][VEXNUM+1];//邻接矩阵;
	int val[VEXNUM+1][VEXNUM+1];//权值;
};
typedef struct{//记录已加入最小生成树的边的情况:端点、权值;
   int a;
   int v;
   int cost;
}closedge;

void create(struct Graph *);//创建图;
void prim(closedge  clo[ARCNUM],struct Graph *);//实现prim

void main()
{  
	closedge  clo[ARCNUM];
	struct Graph *g=NULL;
	g=(struct Graph *)malloc(sizeof(struct Graph));//分配空间;
	create(g);
	prim(clo,g);
}

void prim(closedge  clo[ARCNUM],struct Graph *g){
	int i,j,k,q,w;
	for(i=1;i<=VEXNUM;i++){
		s_set[i]=0;
	}
	
	s_count=0;
	vs_count=VEXNUM;
	s_set[1]=1;s_count++;
	vs_count--;

	while(true){
		int x=MAX_VAL;
		for(j=1;j<=VEXNUM;j++){	
			if(s_set[j]==1){	
				for(k=1;k<=VEXNUM;k++){	
					if((k!=j)&&(s_set[k]==0)){	
						if(x>(g->val[k][j])&&g->val[k][j]!=0)	
						{
							x=g->val[k][j];
							q=j;w=k;
						}
					}
				}
			}
		}
		clo[s_count-1].a=q;clo[s_count-1].v=w;clo[s_count-1].cost=x;
		printf("结点A:%d   结点B:%d   边:%d\n",clo[s_count-1].a,clo[s_count-1].v,clo[s_count-1].cost);
		s_set[w]=1;s_count++;
		vs_count--;
		if(vs_count==0)
			break;
	}
}

void create(struct Graph *g)
{
	int i,j,n,x,y,z;
	FILE *fp;
	fp=fopen("E:\\prim.txt","r");
	for(n=1;n<=VEXNUM;n++)
	    g->vexs[n]=n; 
	for(i=1; i<=VEXNUM; i++)
        for(j=1; j<=VEXNUM; j++){
			g->a[i][j] = 0;
			g->a[j][i] = g->a[i][j];
		}
	for(i=0; i<ARCNUM; i++){
		//fscanf(fp,"%d,%d,%d",&x,&y,&z);错误输入格式
		fscanf(fp,"%d%d%d",&x,&y,&z);//	printf("%d %d %d\n",x,y,z);
		g->a[x][y] = 1;
		g->a[y][x]=g->a[x][y];
		g->val[x][y]=z;
		g->val[y][x]=g->val[x][y];
	}
	fclose(fp);
	for(i=1; i<=VEXNUM; i++)
	{
		for(j=1; j<=VEXNUM; j++)
			if(g->val[i][j]<0)
				g->val[i][j]=0;
	}
/**可以显示图的邻接矩阵
	for(i=1; i<=VEXNUM; i++)
	{
		for(j=1; j<=VEXNUM; j++)
		{
				printf("%d\t",g->a[i][j]);
		}
		 printf("\n");
	}
	printf("\n");printf("\n");printf("\n");
	for(i=1; i<=VEXNUM; i++)
	{
		for(j=1; j<=VEXNUM; j++)
			if(g->val[i][j]>0)
				printf("%d\t",g->val[i][j]);
			else{
				g->val[i][j]=0;
				printf("%d\t",g->val[i][j]);
			}
		 printf("\n");
	}
*/
}

二、最短路径

#include<stdio.h>
#include<stdlib.h>

#define VEXNUM 6//顶点数
#define ARCNUM 10//边数
#define INT_MAX 10000//先定义最大权值;

struct Graph{
	int vexs[VEXNUM+1];//顶点数组;
    int a[VEXNUM+1][VEXNUM+1];//邻接矩阵;
	int val[VEXNUM+1][VEXNUM+1];//权值;
};

void create(struct Graph *);//创建图;
void min_length(struct Graph *);

void main()
{  
	struct Graph *g=NULL;
	g=(struct Graph *)malloc(sizeof(struct Graph));//分配空间;
	create(g);
	min_length(g);
}

void create(struct Graph *g)
{
	int i,j,n,x,y,z;
	FILE *fp;
	fp=fopen("E:\\min1.txt","r");
	for(n=1;n<=VEXNUM;n++)
	    g->vexs[n]=n; 
	for(i=1; i<=VEXNUM; i++)
        for(j=1; j<=VEXNUM; j++){
			g->a[i][j] = 0;
			g->a[j][i] = g->a[i][j];
		}
	for(i=0; i<ARCNUM; i++){
		//fscanf(fp,"%d,%d,%d",&x,&y,&z);错误输入格式
		fscanf(fp,"%d%d%d",&x,&y,&z);//	printf("%d %d %d\n",x,y,z);
		g->a[x][y] = 1;
		g->a[y][x]=g->a[x][y];
		g->val[x][y]=z;
		g->val[y][x]=g->val[x][y];
	}
	fclose(fp);
	for(i=1; i<=VEXNUM; i++)
	{
		for(j=1; j<=VEXNUM; j++)
			if(g->val[i][j]<0)
				g->val[i][j]=0;
	}

	for(i=1; i<=VEXNUM; i++)
	{
		for(j=1; j<=VEXNUM; j++)
		{
				printf("%d\t",g->a[i][j]);
		}
		 printf("\n");
	}
	printf("\n");printf("\n");printf("\n");
	for(i=1; i<=VEXNUM; i++)
	{
		for(j=1; j<=VEXNUM; j++)
			if(g->val[i][j]>0)
				printf("%d\t",g->val[i][j]);
			else{
				g->val[i][j]=0;
				printf("%d\t",g->val[i][j]);
			}
		 printf("\n");
	}
}

void min_length(struct Graph *g)
{
	int disk[VEXNUM+1];
	int pre[VEXNUM+1];
	int i,k,x,y;
	int s=1;
	for(i=1;i<=VEXNUM;i++){
		pre[i]=0;
		if(g->a[1][i]==1)
			disk[i]=g->val[1][i];
		else
			disk[i]=INT_MAX;
	}
	
	disk[1]=0;pre[1]=1;
printf("删除结点:1\n");

	while(s<VEXNUM){
		int min=INT_MAX;
		for(i=1;i<=VEXNUM;i++)
			if(pre[i]==0&&min>disk[i])
				min=disk[i];
		for(i=1;i<=VEXNUM;i++)
			if(pre[i]==0&&min==disk[i]){
				k=i;
				break;
			}		pre[k]=1;
printf("删除结点:%d\n",k);
		for(i=1;i<=VEXNUM;i++)
		{
			if(pre[i]==0&&g->a[k][i]==1){
				x=disk[i];y=disk[k]+g->val[i][k];
				if(x>y)
					disk[i]=y;
			}
		}
		s++;
	}
for(i=1;i<=VEXNUM;i++)
	printf("disk[%d]=%d\n",i,disk[i]);//for(i=1;i<=VEXNUM;i++)

}




floyd:任意点之间最短路径
typedef struct          
{        
    char vertex[VertexNum];                                //顶点表         
    int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表         
    int n,e;                                               //图中当前的顶点数和边数         
}MGraph; 

void Floyd(MGraph g)
{
   int A[MAXV][MAXV];
   int path[MAXV][MAXV];
   int i,j,k,n=g.n;
   for(i=0;i<n;i++)
      for(j=0;j<n;j++)
      {   
             A[i][j]=g.edges[i][j];
            path[i][j]=-1;
       }
   for(k=0;k<n;k++)
   { 
        for(i=0;i<n;i++)
           for(j=0;j<n;j++)
               if(A[i][j]>(A[i][k]+A[k][j]))
               {
                     A[i][j]=A[i][k]+A[k][j];
                     path[i][j]=k;
                } 
     } 
}

三、图的邻接表存储

#include <stdio.h>  
#include <stdlib.h>  
  
#define  MaxVertexNum 4783  
  
typedef char VertexType;  //自定义定点类型,有11837
int[] array = new int{1,7,8,9,8,3,9,3,5,4,1},自定义数组
typedef struct node   //边表节点  
{  
   int adjvex;  
   node* next;  
}EdgeNode;  
  
typedef struct     //顶点表节点  
{  
   VertexType vertex;  
   EdgeNode* firstedge;  
}VertexNode;  
  
typedef VertexNode AdjList[MaxVertexNum];  //自定义定点表节点类型
  
typedef struct   
{   
    AdjList adjlist;  
    int n,e;  //顶点数跟边数
}ALGraph; //图的结构体 
  
void create(ALGraph*);  
  
void main()  
{  
   ALGraph* G= (ALGraph*)malloc(sizeof(ALGraph));  //创建图变量,并且分配空间
   create(G);  
   for (int i=0;i< G->n;i++)  
   {  
       printf("%d->",i);  
       while(G->adjlist[i].firstedge!=NULL)  
       {  
            printf("%d->",G->adjlist[i].firstedge->adjvex);  
            G->adjlist[i].firstedge=G->adjlist[i].firstedge->next;  
  
       }  
       printf("\n");  
   }  
}  
void create(ALGraph* G)  
{  
    int i,j,k,w,v;  
    EdgeNode *s;  
    printf("读入顶点数和边数");  
    scanf("%d,%d",&G->n,&G->e);  
  
    
   for (i=0;i<G->n;i++) //初始化 
   {  
       fflush(stdin);  //用来清空输入缓存,以便不影响后面输入的东西
       printf("建立顶点表");  
       G->adjlist[i].vertex=getchar();  
       G->adjlist[i].firstedge=NULL;  
   }  
   printf("建立边表\n");  
   for (k=0;k<G->e;k++)  
   {  
       printf("读入(vi-vj)的顶点对序号");  
       scanf("%d,%d",&i,&j);  
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=j;  
       s->next=G->adjlist[i].firstedge;  //插入表头  
       G->adjlist[i].firstedge=s;  
	   //如果是无向图,则需要创建下面操作
      /* s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=i;  
       s->next=G->adjlist[j].firstedge;  
       G->adjlist[j].firstedge=s;  */
  
   }  
}