图论:最短路径:广度优先搜索(C语言实现)

图论:最短路径(广度优先搜索、C语言实现)
	要用到的数据结构有:
						队列、表、邻接表
	分为六个文件-
				|--Main.c 应用文件:main函数所在。读取各边到邻接表,然后调用计算机最小路径函数。求解。
				|--code.c  最小路径函数:最小路径函数所在。
				|--Queue.c 数据结构:队列
				|--Table.c 数据结构:表
				|--AdjList.c数据结构:邻接表
				|--Graph.h 将所有数据结构文件包含进来

	邻接表和队列的源泉代码可以从文章列表中找到。
	算法为广度优先搜索。将路径和点记录在一张表中。最后用打印函数递归的打印出路径。思路可见《数据结构与算法分析》。
	各文件源代码如下:
Graph.h:#ifndef _Graph_h
#include "Queue.c"
#include "Table.c"
#endif                             

Main.c:
#include "code.c"
int main()
{
    Vertex Graph = NULL ;    Table T ;
    int x, y, s, a ;
    /*读取各边并插入*/
    for(scanf("%d %d", &x, &y); x != -1 ; scanf("%d %d", &x, &y))
        Graph = InsertEdge(x, y, Graph) ;
	/*创建用于簿记的表,并初化始表:将图中各点格式化入表中*/
    T = CreatTable(SizeOfGraph(Graph)) ;
TableInit(T, Graph)       ;
/*获取起点*/
    printf("Input the start vertex: ") ;
scanf("%d", &s) ;
/*计算各点的最短路径,并记录表中*/
    ShortestPath(s, Graph, T) ;
    /*得到终点*/
    printf("Input the aim vertex: ") ;
scanf("%d", &a) ;
/*打印出该路径,未尾会*/
    TablePrint(s, a, T) ;
printf("\n") ;
/*释放内存*/
    GraphDestory(Graph) ;
TableDestory(T) ;

    return 0;
}
code.c:
#include "Graph.h"

void ShortestPath(int S, Vertex Graph, Table T)
{
    Queue Q ; int NumVertex ;
    int tmp ; int V, W ;
    Ind_Node Ind ; int DistCount = 0;
//init what should be init
/*计算图中的点数*/
NumVertex = SizeOfGraph(Graph) ;
/*创建队列*/
    Q = CreatQueue(NumVertex) ;
//enter the start vertex into queue
/*找到起点*/
tmp = TableFind(S, T)      ;
/*初始化起点*/
    T->Array[tmp].Know = True  ;
    T->Array[tmp].Path = 0     ;
T->Array[tmp].Dist = 0     ;
/*将起点推入队列之中,以驱动下面的代码*/
    Enqueue(tmp, Q)            ;
    /*第一次运行至此,队列不为空,因为插入起点*/
    while(!QueueIsEmpty(Q))
{
	/*读取一点*/
        V = Dequeue(Q) ;
        /*读取V的各个入度*/
        Ind = (T->Array[V].prototype)->Indegree ;
        while(Ind != NULL)
        {
			/*W为当前读取到的入度点*/
            W = TableFind(Ind->Number, T) ;
            if(T->Array[W].Dist == Infinity)
            {
				/*如果W以前没有处理过,那么进行处理*/
                T->Array[W].Dist = T->Array[V].Dist +1 ;
                T->Array[W].Path = (T->Array[V].prototype)->Number ;
				/*然后推入队列之中*/
                Enqueue(W, Q) ;
            }
			/*处理下一入度点*/
            Ind = Ind->Next ;
        }
}
				/
    QueueDestory(Q) ;
}
 
Table.c:
#include <stdio.h>
#include <stdlib.h>
#include "AdjList.c"
#include "limits.h"
#define Infinity INT_MAX
#define True 1
#define False 0
typedef struct table_element_tag
{
	/*将向邻接表中的点*/
Vertex prototype ;
/*路径长度*/
    int Dist ;
	/*记录该点在最短路径中的上一个点。*/
    int Path ;
}*TableElement ;
typedef struct table_tag
{
	/*这里是表头,第一个是记录表大小,第二个是数组(数组实现表)*/
    int Size ;
    TableElement Array ;
}*Table ;

Table CreatTable(int Max)
{
	/*分配好内存,返回*/
    Table T ;
    T = calloc(1, sizeof(struct table_tag)) ;
    if(!T) { fprintf(stderr, "Out of space!\n"); exit(1) ;}
    T->Array = calloc(Max, sizeof(struct table_element_tag)) ;
    if(!T->Array){ fprintf(stderr, "Out of space!") ; exit(1) ;}
    T->Size = Max ;
    return T ;
}
void TableInit(Table T, Vertex Graph)
{
/*将表中各点记录表中*/
    int i = 0;
    while(Graph != NULL && i < T->Size)
    {
        //calloc will init Know
        T->Array[i].prototype = Graph ;
		/*记录为无穷大,表示该点未知*/
        T->Array[i].Dist = Infinity ;
        T->Array[i].Path = Infinity ;
        i++ ;
        Graph = Graph->Next ;
    }
}
int TableFind(int f, Table T)
{
    TableElement te ; int size ; int i ;
    if(!T){ fprintf(stderr, "Graph was empty or miss!\n") ; exit(1) ;}
    te = T->Array ; size = T->Size ;
    for( i = 0; i < size; i++)
        if( (te[i].prototype)->Number == f)
            break ;
    if(i < size)
        return i ;
    else		/*如果没有找到就返回无穷大*/
        return Infinity ;
}
void TablePrint(int s, int a, Table T)
{
    int tmp ;
    if(a != s)
    {
        tmp = TableFind(a, T) ;
        if(tmp == Infinity){ fprintf(stderr, "No Found the vertex: %d\n", a) ; exit(1) ;}
        TablePrint(s, T->Array[tmp].Path, T) ;
        printf(" to ") ;
    }
    printf("%d", (T->Array[TableFind(a, T)].prototype)->Number) ;
}
void TableDestory(Table T)
{
	/*释放内存*/
    if(T)
    {
        if(T->Array)
            free(T->Array) ;
        free(T) ;
    }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值