图的经典算法与应用

图的经典算法与应用

*图的存储结构:邻接矩阵

*DFS BFS

*Prim()算法

求最短路径:Dijkstra()算法

#include<stdio.h>
#define maxsize 100

typedef struct {
	int no;   //the number of vertex
	//char info;		additional information
}VertexType;

typedef struct{
	int edges[maxsize][maxsize];		//weight
	int n,e;
	VertexType vex[maxsize];		//stores node information
}MGraph;

void CreatMGraph(MGraph &g)
{
	int i,j;
	g.n=5;		//five node
	g.e=7;		//seven edge
	for(i=1;i<6;i++){
		for(j=1;j<6;j++){
			g.edges[i][j]=0;  	//	initialize
		}
	}
	g.edges[1][2]=2;
	g.edges[1][5]=3;
	g.edges[2][1]=2;
	g.edges[2][3]=4;
	g.edges[2][4]=5;
	g.edges[2][5]=6;
	g.edges[3][2]=4;
	g.edges[3][4]=7;
	g.edges[3][5]=1;
	g.edges[4][2]=5;
	g.edges[4][3]=7;
	g.edges[4][5]=8;
	g.edges[5][1]=3;
	g.edges[5][2]=6;
	g.edges[5][4]=8;
	g.edges[5][3]=1;    
    for(i=1;i<6;i++){
        g.vex[i].no=i;
    }
    printf("the MGraph is :\n");
    printf("	1	2	3	4	5\n\n");
    for(i=1;i<6;i++){
        printf("%d\t",i);
        for(j=1;j<6;j++){
            printf("%d\t",g.edges[i][j]);
        }
        printf("\n\n");
    }
    return;
}

bool visit[maxsize]={false};				//DFS
void DFS(MGraph g,int u)
{
	visit[u]=true;
	printf("%d ",u);
	int v;
	for(v=1;v<=g.n;v++){
		if(visit[v]==false&&g.edges[u][v]!=0){
			DFS(g,v);
		}
	}
}

void DFSTrave(MGraph g)
{
	int u;
	for(u=1;u<=g.n;u++){
		if(visit[u]==false){
			DFS(g,u);
		}
	}
}

//BFS
bool visit2[maxsize]={false};
void BFS(MGraph g,int v)
{
	int Q[maxsize];
	int front=0,rear=0;
	int j;
	visit2[v]=true;
	printf("%d ",v);
	rear=(rear+1)%maxsize;
	Q[rear]=v;
	while(front!=rear)
	{
		front=(front+1)%maxsize;
		j=Q[front];
		int u;
		for(u=1;u<=g.n;u++)
		{
			if(visit2[u]==false&&g.edges[j][u]!=0)
			{
				rear=(rear+1)%maxsize;
				Q[rear]=u;
				visit2[u]=true;
				printf("%d ",u);
			}
		}
	}
}
void BFSTrave(MGraph g)
{
	int i;
	for(i=1;i<=g.n;i++)
	{
		if(visit2[i]==false)
		{
			BFS(g,i);
		}
	}
}

//最小生成树
void Prim(MGraph g,int v0,int &sum)
{
	int lowcost[maxsize],vest[maxsize],v;
	int i,j,k,min;
	v=v0;
	for(i=1;i<=g.n;i++)
	{
		if(g.edges[v0][i]==0)
		{
			lowcost[i]=32767;
		}
		else
		{
			lowcost[i]=g.edges[v0][i];
		}
		vest[i]=0;
	}
	sum=0;
	vest[v0]=1;
    for(i=1;i<=g.n;i++)
    {
        min=1000;
        for(j=1;j<=g.n;j++)
        {
            if(vest[j]==0&&lowcost[j]<=min)
            {
                min=lowcost[j];
                k=j;
            }
        }
        vest[k]=1;
        v=k;
        sum=sum+min;
        for(j=1;j<=g.n;j++)
        {
            if(vest[j]==0&&g.edges[v][j]<=lowcost[j]&&g.edges[v][j]!=0)
            {
                lowcost[j]=g.edges[v][j];
            }
        }
    }
}

//Dijkstra最短路径
//dist[i]表示当前已找到的从V到每个终点i的最短路径长度
//path[i]中保存从v到i最短路径上i的前一个顶点
//set[i]=0表示i没有被并入最短路径,set[i]=1表示已经被并入最短路径
void Dijkstra(MGraph g,int v,int dist[],int path[])
{
    int set[maxsize];
    int min,i,j,u;
    for(i=1;i<g.n+1;i++)
    {
        if(g.edges[v][i]!=0)
            dist[i]=g.edges[v][i];
        else
            dist[i]=32767;
        set[i]=0;
        if(g.edges[v][i]!=0)
            path[i]=v;
        else
            path[i]=-1;
    }
    set[v]=1;
    path[v]=-1;
//初始化结束
    for(i=1;i<g.n+1;i++)
    {
        min =32767;
//每次从剩余顶点中选出一个顶点,通往这个顶点的路径在通往所有顶点的路径中最短
        for(j=1;j<=g.n;j++)
        {
            if(set[j]==0&&dist[j]<min)
            {
                u=j;
                min=dist[j];
            }
        }
        set[u]=1;
        for(j=1;j<=g.n;j++)
        {
            if(set[j]==0&&dist[u]+g.edges[u][j]<dist[j])
            {
                dist[j]=dist[u]+g.edges[u][j];
                path[j]=u;
            }
        }
    }
}
//函数结束时,dist中存放了v到其余顶点的最短路径长度,path中存放了v到其余顶点的最短路径长度

//打印从源点到任何一个顶点最短路径上所经历的所有顶点
void PrintfPath(int path[],int a)
{
    int stack[maxsize];
    int top=-1;
    while(path[a]!=-1)
    {
        stack[++top]=a;
        a=path[a];
    }
    stack[++top]=a;
    while(top!=-1)
    {
        printf("%d ",stack[top--]);
    }
}
int main() {
	MGraph g;
	CreatMGraph(g);
	printf("深度优先遍历结果是:\n");
	DFSTrave(g);
	printf("\n\n");

	printf("广度优先遍历结果是:\n");
	BFSTrave(g);
	printf("\n\n");

	int sum=0;
	printf("最小生成树花费为:\n");
	Prim(g,1,sum);
	printf("%d \n",sum);

    int path[maxsize];
    int dist[maxsize];
    int i;
    Dijkstra(g,1,dist,path);
    for(i=1;i<=g.n;i++)
    {
        printf("从点1到%d的最短路径为:\n",i);
        PrintfPath(path,i);
        printf("\n");
    }
    return 1;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值