DJ(附带与最小生成树prime算法比较部分)

#include<stdio.h>/*代码修改自百度百科迪杰斯特拉算法的c语言版本*/
#include<stdlib.h>
#define max1 2020  //原词条这里的值太大,导致溢出,后面比较大小时会出错
int a[1000][1000];
int d[100];//d表示源节点到该节点的最小距离
int p[100];//p标记访问过的节点
int i, j, k;
int n;//n代表点数
int main()
{
	//printf("请输入点数5");scanf("%d",&n);
	n=5;
    int    min1;
	int a[5][5] = {{2020, 8, 2020, 4, 2020},  {8, 2020, 7, 5, 12},  {2020, 7, 2020, 11, 6},  {4, 5, 11, 2020, 3},  {2020, 12, 6, 3, 2020},} ;

    for( i=0; i<n; i++)
        d[i]=max1;
    d[0]=0;
    for(i=1;i<n;i++)
    {
        min1 = max1;
        //下面这个for循环的功能类似冒泡排序,目的是找到未访问节点中d[j]值最小的那个节点,
        //作为下一个访问节点,用k标记,找最近的k
        for(j=1;j<n;j++)
            if(!p[j]&&d[j]<min1)
            {
                min1=d[j];
                k=j;
            }
        
        p[k] = 1; //置1表示第k个节点已经访问过了
        for(j=1;j<n;j++)//更新未访问点距离
            if(a[k][j]!=0&&!p[j]&&d[j]>d[k]+a[k][j])
                d[j]=d[k]+a[k][j];
    }
    //最终输出从源节点到其他每个节点的最小距离
    for(i=0;i<n;i++)
        printf("%d->",d[i]);
    return 0;
}

两者比较的整体代码:

#include<stdio.h>
#include<stdlib.h>
#define max1 2020  //原词条这里的值太大,导致溢出,后面比较大小时会出错
int a[1000][1000];
int d[100];//d表示源节点到该节点的最小距离
int visit[100];//visit标记访问过的节点
int i, j, k;
int n;//n代表点数


#define INFINITY  2020;

typedef struct closedge //保存链接边的辅助的类型
{
 int adjvex;
 int lowcost; 
} closedge;

int Prime()//图的最小生成树算法
{  

	int arr[8][8] = {{2020, 8, 2020, 4, 2020},  
					 {8, 2020, 7, 5, 12},  
					 {2020, 7, 2020, 11, 6},  
					 {4, 5, 11, 2020, 3},  
					 {2020, 12, 6, 3, 2020},  
					} ;

	 int u=0;/*从❤第二个❤顶点开始构造图的最小生成树*/
	 closedge closedge[5];
	 int  j,k,v,min;
     /*初始化*/
	 for(j=0;j<5;j++)/*生成树与其他节点的最小距离数组初始化,其中5是顶点的个数*/
	 { closedge[j].adjvex=u;
	 closedge[j].lowcost=arr[u][j];/*初始化arr[1][j]*//*初始化({8, 2020, 7, 5, 12},)*/
	 }
	 closedge[u].lowcost=0;/*初始点,并入最小生成树*/
	 printf("%d->",u);
	
	 for(j=0;j<5-1;j++)/*5是顶点的个数,只需再运行四次,取四次树与节点的最小值,并入其他的四个点*/
	 {
	    min=2020;  
	 for(v=0;v<5;v++)/*关键:寻找最短的点*/
		 if(closedge[v].lowcost!=0 && closedge[v].lowcost<min)/*如果v点没有并入树,寻找距离最短的k点*/
		 {
		    min=closedge[v].lowcost;     k=v;
	     }
	 
		 closedge[k].lowcost=0;/*将顶点k并入U中*/
		 printf("%d->",k);

		 /*❤ k并入后,更新“其他未并入到当前树的关键节点的”最短距离,修改closedge【n】中的各个元素的值 ❤ */
		 for(v=0;v<5;v++)
			 if(arr[v][k]<closedge[v].lowcost)
		     {
				 closedge[v].lowcost=arr[v][k];
				 closedge[v].adjvex=k;
			 }

      }
	
	printf("prime算法执行结束,以上为选择到当前树最近的顶点的序列\n");
	return 0;

}

int dij()
{
		//printf("请输入点数5");scanf("%d",&n);
	n=5;
    int    min1;
	int a[5][5] = {{2020, 8, 2020, 4, 2020},  
					 {8, 2020, 7, 5, 12},  
					 {2020, 7, 2020, 11, 6},  
					 {4, 5, 11, 2020, 3},  
					 {2020, 12, 6, 3, 2020},  
					} ;



    for( i=0; i<n; i++)
        d[i]=max1;
    d[0]=0;
    for(i=1;i<n;i++)
    {
        min1 = max1;
        //下面这个for循环的功能类似冒泡排序,目的是找到未访问节点中d[j]值最小的那个节点,
        //作为下一个访问节点,用k标记,找最近的k
        for(j=1;j<n;j++)
            if(!visit[j]&&d[j]<min1)
            {
                min1=d[j];
                k=j;
            }
        
        visit[k] = 1; //置1表示第k个节点已经访问过了
        for(j=1;j<n;j++)//更新“源点到未访问”点距离
            if(a[k][j]!=0&&!visit[j]&&d[j]>d[k]+a[k][j])
                d[j]=d[k]+a[k][j];
    }
    //最终输出从源节点到其他每个节点的最小距离
    for(i=0;i<n;i++)
        printf("%d->",d[i]);
	return 0;
}



	 
 



int main()
{
	Prime();printf("按任意键继续");dij();
	int aaahhh=0;scanf("%d",&aaahhh); /*防止运行完一闪而过*/return 0;
}

两者比较的相同代码:

在未并入(访问)的点中寻找距离最短的k:
prime:
min=2020;
 for(v=0;v<5;v++)/*关键:寻找最短的点*/
		 if(closedge[v].lowcost!=0 && closedge[v].lowcost<min)/*如果v点没有并入树,寻找距离最短的k点*/
		 {
		    min=closedge[v].lowcost;     k=v;
	     }
         closedge[u].lowcost=0;
dij:
min1 = max1;
        //下面这个for循环的功能类似冒泡排序,目的是找到未访问节点中d[j]值最小的那个节点,
        //作为下一个访问节点,用k标记,找最近的k
        for(j=1;j<n;j++)
            if(!visit[j]&&d[j]<min1)
            {
                min1=d[j];     k=j;
            }
        
        visit[k] = 1; //置1表示第k个节点已经访问过了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值