数据结构学习第9章 - 最短路径(Dijstra算法)

最短路径问题

在《图的存储与遍历》的基础上,实现求最短路径的Dijstra算法,并将该算法用于求下图从顶点A到其它各顶点的最短路径,以验证算法的正确性。


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

#define MaxVertexNum 20                                    //最大定点数设为100

#define MAXSIZE 20

#define INF 999                                           //定义无穷大

/****************图的邻接矩阵定义 *******************/
typedef char VertexType;                                //定点类型设为字符型
typedef int EdgeType;                                    //边的权值设为字符型
typedef struct
{
    VertexType vexs[MaxVertexNum];                        //顶点表
    EdgeType edges[MaxVertexNum][MaxVertexNum];            //邻接矩阵,即边表
    int n;                                                 //n为顶点数
    int e;                                                //e为边数
}MGraph;


/****************图的邻接表定义 *******************/
typedef struct node                                        //边表结点
{
    int adjvex;                                            //邻接点域
    EdgeType info;                                        //数据域
    struct node *next;                                    //指向下一个邻接点的指针域  
} EdgeNode;
typedef struct vnode                                    //顶点表结点
{
    VertexType vertex;                                    //顶点域
    EdgeNode *firstedge;                                //边表头指针
}VertexNode;
typedef struct                                        
{
    VertexNode AdjList[MaxVertexNum];                    //顶点表
    int n;                                                //顶点表顶点数
    int e;                                                //顶点表边数
}ALGraph;


/****************队列的类型及各种操作 *******************/
typedef int datatype;

typedef struct Queue
{
    datatype data[MAXSIZE];    
    datatype top;
    datatype bottom;
}Queue;  

//初始化
void InitQueue(Queue * p)
{
    p->top = 0;
    p->bottom = 0;
}

//入队
void EnQueue(Queue *p,datatype val)
{
    p->data[p->bottom] = val;
    (p->bottom)++;
    p->bottom = (p->bottom) % MAXSIZE;  
}

//出队
datatype DeQueue(Queue *p)
{
    datatype p1;

    p1 = p->top;
    (p->top)++;
    p->top = ((p->top) + MAXSIZE) % MAXSIZE;
    return p->data[p1];
}

//队列为空
int QueueEmpty(Queue *p)
{
    if(p->top == p->bottom)
    {
        return -1;
    }
}
 
/****************图的创建与打印 *******************/
//创建邻接矩阵
void CreateMGraph(MGraph *G)
{
    int i,j,k,w,weight;
    char ch;
    printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
    scanf("%d,%d",&(G->n),&(G->e));
    printf("请输入顶点信息:\n");
    for(i = 0; i < G->n; i++)
    {
        getchar();
        scanf("%c",&(G->vexs[i]));    
    }

    for(i = 0; i < G->n; i++)
    {
        for(j = 0; j < G->n; j++)
        {
            
            if(i == j)
            {
                G->edges[i][j] = 0;
                
            }
            else
            {
                G->edges[i][j] = INF;
            
            }
            
        }
    }
    
    printf("请输入每条边对应的两个顶点的序号和权值(输入格式为:i,j,权值):\n");
    for(k = 0; k < G->e; k++)
    {
        scanf("%d,%d,%d",&i,&j,&weight);
        G->edges[i][j] = weight;
    }
}

//打印邻接矩阵
void printMGraph(MGraph *G)
{
    int i,j;
    printf("邻接矩阵为:\n");
    for(i = 0; i < G->n; i++)
    {
        printf("V%-4c ",G->vexs[i]);
        for(j = 0; j < G->n; j++)
        {
            if(G->edges[i][j] == INF)
                printf("∞   ");
            else
                printf("%-4d ",G->edges[i][j]);
        }
        printf("\n");
    }
}

//创建邻接表
void MGraphtoALGraph(MGraph *mG,ALGraph *alG)
{
    int i,j,k;
    EdgeNode * s;
    alG->n = mG->n;
    alG->e = mG->e;
    for(i = 0; i < alG->n; i++)
    {
        alG->AdjList[i].vertex = mG->vexs[i];
        alG->AdjList[i].firstedge = NULL;
    }
    for(i = 0; i < mG->n; i++)
    {
        for(j = 0; j < mG->n; j++)
        {
            if(mG->edges[i][j] != 0 && mG->edges[i][j] != INF)
            {
                s = (EdgeNode *)malloc(sizeof(EdgeNode));
                s->adjvex = j;
                s->next = alG->AdjList[i].firstedge;
                s->info = mG->edges[i][j];
                alG->AdjList[i].firstedge = s;
            }
        }
    }    
}

//打印邻接表
void printALGraph(ALGraph *alG)
{
    int i,j,k;
    EdgeNode *p;
    printf("邻接表为:\n");
    for(i = 0; i < alG->n; i++)
    {
        printf("V%c",alG->AdjList[i].vertex);
        p = alG->AdjList[i].firstedge;
        while(p != NULL)
        {
            printf("->%d,%d",p->adjvex,p->info);
            p = p->next;
        }
        printf("\n");
    }
}

/****************图的深度优先遍历 *******************/
int visited[MaxVertexNum];

//对邻接矩阵存储的图点进行DFS搜索
void DFST(MGraph *mG, int i)
{
    if(visited[i] == 0)
    {
        int j;
        printf("visit vertex: %c\n",mG->vexs[i]);
        visited[i] = 1;
        for(j = 0; j < mG->n; j++)
        {
            if(mG->edges[i][j] != 0 && mG->edges[i][j] != INF)
            {
                j;
                DFST(mG, j);
            }
        }
    }
}

//对邻接矩阵存储的图点进行DFS搜索
void DFSTraverse1(MGraph *mG)
{
    int i,j,k;
    memset(visited, 0, sizeof(mG->n));                
    for(i = 0; i < mG->n; i++)
    {
        if(visited[i] == 0)
        {
            DFST(mG, i);
        }
    }
}


//对邻接表存储的图进行DFS搜索
void DFSAL(ALGraph *alG, int i)
{
    EdgeNode * p;
    printf("visit vertex: %c\n",alG->AdjList[i].vertex);
    visited[i] = 1;
    p = alG->AdjList[i].firstedge;
    while(p != NULL)
    {
        if(visited[p->adjvex] == 0)
        {
            DFSAL(alG,p->adjvex);    
        }    
        p = p->next;
    }    
}


//对邻接表存储的图进行DFS搜索
void DFSTraverse2(ALGraph *alG)
{
    int i;
    for(i = 0; i < alG->n; i++)
    {
        visited[i] = 0;
    }
    for(i = 0; i < alG->n; i++)
    {
        if(visited[i] == 0)
        {
            DFSAL(alG,i);
        }
    }
}

/****************图的广度优先遍历 *******************/
//对邻接矩阵存储的图进行BFS搜索
void BFSM(MGraph *mG,int k)
{
    int i,j;
    Queue Q;
    InitQueue(&Q);
    printf("visit vertex: %c\n",mG->vexs[k]);
    visited[k] = 1;
    EnQueue(&Q,k);
    while(QueueEmpty(&Q) != -1)
    {
        i = DeQueue(&Q);
    
        for(j = 0; j < mG->n; j++)
        {
            if(mG->edges[i][j] != 0 && mG->edges[i][j] != INF && visited[j] == 0)
            {
                printf("visit vertex: %c\n",mG->vexs[j]);
                visited[j] = 1;
                EnQueue(&Q,j);
            }    
        }
    }    
}

//对邻接矩阵存储的图进行BFS搜索
void BFSTraverse1(MGraph *mG)
{
    int i;
    for(i = 0; i < mG->n; i++)
    {
        visited[i] = 0;
    }
    for(i = 0; i < mG->n; i++)
    {
        if(visited[i] == 0)
        {
            BFSM(mG,i);
        
        }
    }
}


//对邻接表存储的图进行BFS搜索
void BFSAL(ALGraph *alG, int k)
{
    int i, j;
    Queue Q;                                            //队列  
    InitQueue(&Q);
    EdgeNode *p;
    printf("visit vertex: %c\n",alG->AdjList[k].vertex);
    visited[k] = 1;
    EnQueue(&Q,k);

    while(QueueEmpty(&Q) != -1)
    {
    
        i = DeQueue(&Q);
        p = alG->AdjList[i].firstedge;
        
        while(p != NULL && visited[i] == 0)
        {
            
            i = p->adjvex;
            printf("visit vertex: %c\n",alG->AdjList[i].vertex);
            visited[i] = 1;
            EnQueue(&Q,i);
            p = p->next;
        }
    }
}

//对邻接表存储的图进行BFS搜索
void BFSTraverse2(ALGraph *alG)
{
    int i;
    for(i = 0; i < alG->n; i++)
    {
        visited[i] = 0;
    }
    for(i = 0; i < alG->n; i++)
    {
        if(visited[i] == 0)
        {
            BFSAL(alG,i);
        }
    }
}

/****************************************Dijkstra函数*********************************/

void dijkstra(MGraph * mG)
{
    int i,j,k,l,min,v;
    int d[MAXSIZE];
    bool vis[MAXSIZE];
    
    
    for(i = 0; i < mG->n; i++)
    {
        vis[i] = 0;
        d[i] = mG->edges[0][i];
    
    }

    d[0] = 0;
    vis[0] = 1;

    for(i = 1; i < mG->n; i++)
    {
        min = INF;
        v = -1;
        for(j = 0; j < mG->n; j++)
        {
            if(vis[j] == 0 && d[j] < min)
            {
                v = j;
                min = d[j];
            }
        }
        vis[v] = 1;

    
        for(k = 0; k < mG->n; k++)
        {
            
            if(vis[k] == 0 && d[k] > mG->edges[v][k] + min)
            {
                d[k] = mG->edges[v][k] + min;
        
            }
        }
    }
    for(i = 0; i < mG->n; i++)
    {
        printf("%d------%c->%c\n",d[i],mG->vexs[0],mG->vexs[i]);
    }
}


/****************************************main函数*************************************/
int main()
{
    MGraph G;
    ALGraph alG;
    CreateMGraph(&G);
    printMGraph(&G);
    MGraphtoALGraph(&G,&alG);
    printALGraph(&alG);
    printf("对邻接矩阵存储的图点进行DFS搜索:\n");
    DFSTraverse1(&G);
    printf("对邻接表存储的图进行DFS搜索:\n");
    DFSTraverse2(&alG);
    printf("对邻接矩阵存储的图进行BFS搜索:\n");
    BFSTraverse1(&G);
    printf("对邻接表存储的图进行BFS搜索:\n");
    BFSTraverse2(&alG);
    dijkstra(&G);
}

猜你喜欢

转载自blog.csdn.net/guanshanyue96/article/details/89008389
今日推荐