图论--bellman_Ford算法---邻接表实现

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

 

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/yjy188/article/details/8094900
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞