数据结构实验十二 图的遍历及应用

数据结构实验十二 图的遍历及应用

一、【实验目的】

1 理解图的存储结构与基本操作;

2、熟悉图的深度度优先遍历和广度优先遍历算法

3、掌握图的单源最短路径算法

二、【实验内容】

1.根据下图(图见实验11)邻接矩阵,编程实现该图的深度与广度优先遍历算法,输出遍历序列。

2.单源节点最短路径问题

问题描述:求从有向图的某一结点出发到其余各结点的最短路径。

基本要求:

1)有向图采用邻接矩阵表示。

2)单源节点最短路径问题采用Dijkstra算法。

3)输出有向图中从源结点T到其余各结点的最短路径和最短路径值。

三、实验源代码

 #define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<stdlib.h>

#define Max 100

int n;



int book[100] = { 0 };

typedef int ElemType;

typedef struct {

    int a[100][100];

    int numofvex;

    char list[100];

}Matrix;

typedef struct {

    int front, rear, top;

    ElemType queue[Max];

}Q;

Q* qinit()

{

    Q* q;

    q = (Q*)malloc(sizeof(Q));

    q->front = q->rear = q->top = 0;

    return q;

}

int notempty(Q* q)//返回0即为空

{

    if (q->rear == q->front && q->top == 0)

         return 0;

    return 1;

}

void qappend(Q* q, int v)

{

    if (q->top > Max)

    {

         printf("out of space");

         return;

    }

    q->queue[q->rear] = v;

    q->rear = (q->rear + 1) % Max;

    q->top++;

}

void qdelete(Q* q, int *v)

{

    if (q->top == 0)

    {

         printf("lack of element");

         return;

    }

    *v = q->queue[q->front];

    q->front = (q->front + 1) % Max;

    q->top--;

}

Matrix* init()

{

    int i, j;

    Matrix* my = (Matrix*)malloc(sizeof(Matrix));

    for (i = 0; i < n; i++)

         for (j = 0; j < n; j++)

         {

             if (i == j)

                  my->a[i][j] = 0;

             else

                  my->a[i][j] = Max;

         }

    for (i = 0; i < n; i++)

         my->list[i] = i + 'A';

    my->numofvex = n;

    return my;

}

Matrix* create()

{

    char  d, z;

    int i, j, w;

    Matrix* my= init();

    i = j = w = 0;

    printf("请以三元组形式输入\n");

    getchar();

    while (1)

    {

         scanf("%c %c %d", &z,&d,&w);

         getchar();

         i = z - 'A';

         j = d - 'A';

         my->a[i][j] = w;

         if (w == 0&&z=='0'&&d=='0')

             break;

    }

    return my;

}

int getfirstvex(int v, Matrix* my)

{

    int i;

    for (i = 0; i < n; i++)

         if (my->a[v][i] > 0 && my->a[v][i] < Max)

             return i;

    return -1;

}

int getnextvex(int u, int v, Matrix* my)

{

    int i;

    for (i = v + 1; i < n; i++)

         if (my->a[u][i] > 0 && my->a[u][i] < Max)

             return i;

    return -1;

}

void dfs(int v, Matrix* my)

{

    int w;

    book[v] = 1;

    printf("%c ", my->list[v]);

    w = getfirstvex(v, my);

    while (w != -1)

    {

         if (!book[w])

             dfs(w, my);

         w = getnextvex(v, w, my);

    }

}

void bfs(int v, Matrix* my)

{

    Q* q;

    q = qinit();

    int w;

    qappend(q, v);

    book[v] = 1;

    while (notempty(q))

    {

         qdelete(q, &v);

         printf("%c ", my->list[v]);

         w = getfirstvex(v, my);

         while (w != -1)

         {

             if (!book[w])

             {

                  book[w] = 1;

                  qappend(q, w);

             }

             w = getnextvex(v, w, my);

         }

    }

}

void Dijkstra(int v, Matrix* my,int distance1[],int path[])//赋值path[]与distance1[],v为出发点

{

    int i, j,wmin=Max,x=0;

    int* s = (int*)malloc(sizeof(int) * n);//定义访问数组s[]

    for (i = 0; i < n; i++)//初始化path[],distance1[]

    {

         s[i] = 0;

         distance1[i] = my->a[v][i];

         if (my->a[v][i] != Max&& my->a[v][i] != 0&&i!=v)//能直接到达的点进行初步赋值

         {

             path[i] = v;

         }

         else//不能到达即自旋,和无路径

         {

             path[i] = -1;

         }

    }

    s[v] = 1;

    for (x = 1; x < n; x++)//已经访问过一个点所以还剩n-1个点未访问

    {

         wmin = Max;

         for (i = 0; i < n; i++)//找最小权值,且未被访问过

         {

             if (distance1[i] < wmin&&s[i]!=1)

             {

                  j = i;

                  wmin = distance1[i];

             }

         }

         if (wmin == Max)//非连通图总有一个无法到达故距离为Max应该及时退出

             return;

         s[j] = 1;

         for (i = 0; i < n; i++)//看看对distance[]是否有影响,更新

         {

             if (s[i] == 0 && my->a[j][i] > 0 && my->a[j][i] != Max && distance1[i] > distance1[j] + my->a[j][i])

             {

                  distance1[i] = distance1[j] + my->a[j][i];

                  path[i] = j;

             }

         }

    }

}

void print(int m,int v,Matrix*my,int path[])

{

    int x = 0;

    char ch[100];

    if (v == -1)

         printf("%c        ", my->list[m]);

    else

    {

         while (v != -1)

         {

             ch[x] = my->list[v];

             v = path[v];

             x++;

         }

         for (int i = x - 1; i >= 0; i--)

             printf("%c", ch[i]);

         printf(" ");

    }

}

void reset(int* a)

{

    for (int i = 0; i < n; i++)

         a[i] = 0;

}

int main()

{

    Matrix* my ;

    int path[100];

    int distance1[100] = { 0 };

    char c;

    int i, j;

    printf("请输入节点个数:");

    scanf("%d", &n);

    my=create();

    printf("邻接矩阵为:\n");

    for (i = 0; i < n; i++)

    {

         for (j = 0; j < n; j++)

             printf("%d ", my->a[i][j]);

         printf("\n");

    }

    printf("请输入从哪一个节点开始进行深度优先遍历搜索:");

    scanf("%c", &c);

    dfs(c-'A', my);

    getchar();

    printf("\n");

    reset(book);

    printf("请输入从哪一个节点开始进行广度优先遍历搜索:");

    scanf("%c", &c);

    bfs(c-'A', my);

    printf("\n");

    getchar();

    printf("请输入哪一个节点到其他节点的最短路径:");

    scanf("%c", &c);

    Dijkstra(c - 'A', my,distance1,path);

    printf("path[]数组:");

    for (i = 0; i < n; i++)

         printf("%d ", path[i]);

    printf("\n");

    printf("点%c到其他点的最小路径    最小路径权值为\n",c);

    for ( i = 0; i < n; i++)

    {  

         print(c-'A',i, my, path);

         printf("%d\n", distance1[i]);

    }

}

四、实验结果

 

五、实验总结

使用scanf()前应当消除’\n’’ ‘。来确保输入的准确性

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值