bellman_Frod算法
求最短路径。
C语言实现。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 20
#define TRUE 1
#define FALSE 0
#define INTMAX 0xFFFF
#define OK 1
#define ERROR 0
typedef char Type[MAX_LEN];
int visit[MAX_LEN];
typedef struct ArcNode{///-------邻接表节点
int adjvex;
int weight;
struct ArcNode * next;
}ArcNode;
typedef struct VNode{///--------邻接表头
Type data;
int dist;
int path;
ArcNode * firstarc;
}VNode , AdjList[MAX_LEN];
typedef struct ALGraph{///----图
AdjList vertices;
int vexnum;
int arcnum;
//int kind;
}ALGraph;
typedef struct Node{///---------广度优先遍历----链表实现
Type CH;
int x;
struct Node * next;
}Node;
void InitGraph( ALGraph * g )///---------------初始化函数--------------------
{
int i ;
printf("请输入 顶点数 和 边数:\n");
scanf("%d %d",&g->vexnum , &g->arcnum);
printf("请输入 顶点信息 :\n");
for( i = 0 ; i < g->vexnum ; i ++){
scanf("%s",&g->vertices[i].data);
g->vertices[i].firstarc = NULL;
}
}
int LocateVex( ALGraph * g , Type v )///-----------------查找函数----------------
{
int i;
for( i = 0 ; i < g->vexnum ; i++){
if( (strcmp(v , g->vertices[i].data)) == 0 )
return i;
}
}
void CreateAdjList( ALGraph * g )///----------------------邻接表建立有向图函数--------------
{
int i , j , k , weight;
Type v1 , v2 ;
ArcNode * p ;
printf("请输入%d条弧的 两两关系 及 权重 :\n",g->arcnum);
for( k = 0 ; k < g->arcnum ; k ++)
{
scanf("%s %s %d",&v1 , &v2 , &weight);
i = LocateVex( g , v1 );
j = LocateVex( g , v2 );
ArcNode * newnode = ( ArcNode * )malloc(sizeof(ArcNode));
newnode->adjvex = j;
newnode->weight = weight;
newnode->next = NULL;
p = g->vertices[i].firstarc;
if( p == NULL ){
g->vertices[i].firstarc = newnode;
}
else{
while( p->next )
p = p->next;
p->next = newnode;
}
}
}
void Bellman_Floyd( ALGraph * g )///---------------Bellman_Floyd算法------(权值为:+ )--------------------------
{
int i , j , k ;
ArcNode * p ;
g->vertices[0].dist = 0;
g->vertices[0].path = 0;
for( i = 0 ; i < g->vexnum ; i++ )
for( j = 0 ; j < g->vexnum ; j++ )
for( p = g->vertices[j].firstarc ; p != NULL ; p = p->next )
if( g->vertices[p->adjvex].dist > g->vertices[j].dist + p->weight ){
g->vertices[p->adjvex].dist = g->vertices[j].dist + p->weight;
g->vertices[p->adjvex].path = j;
}
}
void ShowPathWay( ALGraph * g )///-------------------- 输出函数--------------------
{
int i;
printf("最短路径:\n");
for( i = 1 ; i < g->vexnum ; i ++ ){
printf("%s-->%s:\n", g->vertices[0].data , g->vertices[i].data);
if( g->vertices[i].dist < INTMAX )
printf("minway: %d\n",g->vertices[i].dist);
if( IndgePathWay( g , i ) ){
ShowWay( g , g->vertices[i].path );
printf("%s\n\n",g->vertices[i].data);
}
else{
printf("ERROR:\n");
printf("no path way\n\n");
}
}
}
int IndgePathWay( ALGraph * g , int k )///------------------判断是否有通路------------------
{
int i;
for( i = 0 ;i < g->vexnum ; i ++ ){
if( k >= 0 && k < g->vexnum ){
if( k == 0 )
return OK;
k = g->vertices[k].path;
}
else
return ERROR;
}
}
void ShowWay( ALGraph * g , int k )///-------------------递归打印----------------------------
{
if( k > 0 && k < g->vexnum ){
ShowWay( g , g->vertices[k].path);
printf("%s-->" , g->vertices[k].data);
}
else if( k == 0 ){
printf("%s-->" , g->vertices[k].data);
}
}
void Visit( ALGraph * g )///-------------初始化路径
{
int i,j;
for( i = 0 ; i <g->vexnum ; i ++){
visit[i] = FALSE;
g->vertices[i].dist = INTMAX;
g->vertices[i].path = INTMAX;
}
}
///-----------------------------深度遍历函数-----------------------------------------
void Dfs( ALGraph * g , int i )
{
visit[i] = TRUE;
printf("%s ",g->vertices[i].data);
ArcNode * p;
p = g->vertices[i].firstarc;
while( p ){
if(!visit[p->adjvex])
Dfs( g , p->adjvex );
else
p = p->next;
}
}
void DfsTraverse( ALGraph * g )
{
int i;
Visit( g );
for( i = 0 ; i <g->vexnum ; i ++)
if(!visit[i])
Dfs(g , i);
}
///-------------------------------------广度遍历---(链表实现)--------------------------
Node * ListBfsTraverse( ALGraph * g , Node * Head )
{
int i;
ArcNode * p;
Head->next = NULL;
Node * Hnew = Head ,* first;
first = Hnew;
Visit( g );
for( i = 0 ; i <g->vexnum ; i ++){
if(!visit[i])
{
Node * pnew = (Node *)malloc(sizeof(Node));
strcpy(pnew->CH , g->vertices[i].data);
pnew->x = i;
pnew->next = NULL;
Hnew->next = pnew;
Hnew = pnew;
visit[i] = TRUE;
p = g->vertices[i].firstarc;
while( p ){
if(!visit[p->adjvex])
{
Node * pnew = (Node *)malloc(sizeof(Node));
strcpy(pnew->CH , g->vertices[p->adjvex].data);
pnew->next = NULL;
pnew->x = p->adjvex;
Hnew->next = pnew;
Hnew = pnew;
visit[p->adjvex] = TRUE;
}
p = p->next;
}
first = first->next;
ArcNode * q;
while( first->next ){
q = g->vertices[first->x].firstarc;
while( q ){
if(!visit[q->adjvex])
{
Node * pnew = (Node *)malloc(sizeof(Node));
strcpy(pnew->CH , g->vertices[q->adjvex].data);
pnew->next = NULL;
pnew->x = q->adjvex;
Hnew->next = pnew;
Hnew = pnew;
visit[q->adjvex] = TRUE;
}
q = q->next;
}
first = first->next;
}
}
}
return Head;
}
void ShowList( Node * Head )
{
Node * p = Head;
while( p->next ){
p = p->next;
printf("%s ",p->CH);
}
printf("\n");
}
///---------------------测试函数---------------------------
void Indge( ALGraph * g )
{
int i ;
ArcNode * p ;
printf("\n------------------------测试邻接表-----------------------\n");
for( i = 0 ; i <g->vexnum ; i ++){
printf("%s ----> ",g->vertices[i].data);
p = g->vertices[i].firstarc;
while( p ){
printf("%s ",g->vertices[p->adjvex].data);
printf("(%d) ",p->weight);
p = p->next;
}
printf("\n\n");
}
}
int main()///----------------------------main()----------------
{
int T;
printf("------------有向图的建立与遍历----邻接表实现---------------------\n");
printf("请输入测试数据组数:\n");
scanf("%d",&T);
while( T -- )
{
ALGraph g;
printf("-------------------初始化--------------------\n");
InitGraph( &g );
printf("-----------------建立有向图------------------\n");
CreateAdjList( &g );
printf("\n\n深度遍历有向图:\n");
DfsTraverse( &g );
printf("\n\n广度遍历有向图:\n");
Node * HEAD = ( Node *)malloc(sizeof(Node));
HEAD = ListBfsTraverse( &g , HEAD );
ShowList( HEAD );
Indge( &g );
Bellman_Floyd( &g );
ShowPathWay( &g );
printf("\n\n-----------------------------------------------------\n");
}
return 0;
}
案例:
————有向图的建立与遍历—-邻接表实现———————
请输入测试数据组数:
2
——————-初始化——————–
请输入 顶点数 和 边数:
7 12
请输入 顶点信息 :
1 2 3 4 5 6 7
—————–建立有向图——————
请输入12条弧的 两两关系 及 权重 :
1 2 2
1 4 1
2 4 3
2 5 10
3 1 4
3 6 5
4 3 2
4 5 2
4 6 8
4 7 4
5 7 6
7 6 1
深度遍历有向图:
1 2 4 3 6 5 7
广度遍历有向图:
1 2 4 5 3 6 7
————————测试邻接表———————–
1 —-> 2 (2) 4 (1)
2 —-> 4 (3) 5 (10)
3 —-> 1 (4) 6 (5)
4 —-> 3 (2) 5 (2) 6 (8) 7 (4)
5 —-> 7 (6)
6 —->
7 —-> 6 (1)
最短路径:
1–>2:
minway: 2
1–>2
1–>3:
minway: 3
1–>4–>3
1–>4:
minway: 1
1–>4
1–>5:
minway: 3
1–>4–>5
1–>6:
minway: 6
1–>4–>7–>6
1–>7:
minway: 5
1–>4–>7