实验四

简介: 实验四  图的基本操作   院 、系  海师计教系  班级 计本二班 学   号  200624101101  姓名  杨振平 完成日期  2007-11-19   源程序名 1.      cpp和222.cpp和图.cpp   一、题目 编制一个演示用邻接矩阵和邻接表存储结构实现的图的深度优先遍历和广度优先遍历算法的程序。

实验四  图的基本操作

 

院 、系

 海师计教系

 班级

计本二班

  

 200624101101

 姓名

 杨振平

完成日期

 2007-11-19  

源程序名

1.      cpp222.cpp和图.cpp

 

一、题目

编制一个演示用邻接矩阵和邻接表存储结构实现的图的深度优先遍历和广度优先遍历算法的程序。另附扩展实现(1:有向图2:无向图3:有向网4:无向网) 4种类型的图的(1.邻接矩阵,2.邻接表,3.深度优先搜索,4.广度优先搜索,5.最小生成树,6.拓扑排序,7.关键路径,8.从某个源点到其余各顶点的最短路径,9.每一对顶点之间的最短路径)图的9种实现程序。(附源代码于尾页//程序1 //程序2 /*扩展实现源代码*/

二、需求分析      

本程序在Windows环境下用用Visual C++编写,完成程序1和程序2的实现:

程序1

void CreatMatrix(adjmatrix GA)       // 建立图的邻接矩阵

void DfsMatrix(adjmatrix GA,int v)  // 从初始点v出发深度优先遍历邻接矩阵GA表示的图

void BfsMatrix(adjmatrix GA,int v)  // 从初始点v出发广度优先遍历邻接矩阵GA表示的图

程序2

void CreatAdjlist(AdjList GL) //建立图的邻接表

void DfsAdjlist(AdjList GL,int v) //从初始点v出发深度优先遍历邻接表GL表示的图

void BfsAdjlist(AdjList GL,int v) //从初始点v出发广度优先遍历邻接表GL表示的图

 

三、概要设计

程序1

/* 定义邻接矩阵类型 */

typedef int adjmatrix[n+1][n+1];

程序2

/* 邻接表的结点类型 */

typedef struct arc

{

int adjvex;

    struct arc *next;}ArcNode;

typedef struct VexNode

{

int vertex;

    ArcNode *firstarc;

}VerNode;

typedef VerNode AdjList[MAXNODE];

三、详细设计

分别对程序1和程序2进行编码设计如下:

//程序1

#include <stdio.h>

#define n 5

#define MAXSIZE 10     //广度优先遍历时所使用的队列的最大容量

#define MaxNum 10000   //定义一个最大数

// 定义邻接矩阵类型

typedef int  adjmatrix[n+1][n+1];  // 0号单元没用

int visited[n+1];                  // 0号单元没用

int arcnum;                        //边的个数

//建立图的邻接矩阵

//程序2

#include <stdio.h>

#include <malloc.h>

#define MAXNODE 10

#define NULL 0

typedef struct arc

{

     int adjvex;

    struct arc *next;

}ArcNode;

typedef struct VexNode

{

     int vertex;

 ArcNode *firstarc;

}VerNode;

typedef VerNode AdjList[MAXNODE];

int visited[MAXNODE];

int vexnum,arcnum;

// 建立图的邻接表

2)图的基本操作如下:

//程序1

//建立图的邻接矩阵

void CreatMatrix(adjmatrix GA)

//从初始点v出发深度优先搜索邻接矩阵GA表示的图

void DfsMatrix(adjmatrix GA,int v)

//从初始点v出发广度优先搜索邻接矩阵GA表示的图

void BfsMatrix(adjmatrix GA,int v)

//程序2

// 建立图的邻接表

void creatgraph(AdjList GL)

    void dfs(AdjList G,int v)

// 从初始点v出发深度优先遍历邻接表GL表示的图

void DfsAdjlist(AdjList GL,int v)

//从初始点v出发广度优先遍历邻接表GL表示的图

void BfsAdjlist(AdjList GL,int v)

四、测试结果

1.程序1

图中有5个顶点

请输入边的个数(限制在110的范围内):6

请输入图的所有边(一条边的两个端点中间用,分隔): ,

1,2 2,3 2,5 3,4 4,5 5,1

请输入深度优先遍历的开始结点:1

深度优先遍历序列是:1,2,3,4,5,

请输入广度优先遍历的开始结点:1

广度优先遍历序列是:1 2 5 3 4 Press any key to continue

2.程序2

请输入顶点个数和边的个数:5 6

请输入顶点(顶点用整型数代表):

1 2 3 4 5

请输入图的所有边(一条边的两个端点中间用,分隔): ,

1,2 2,3 2,5 3,4 4,5 5,1

请输入深度优先遍历的开始结点:1

深度优先遍历序列是:1,5,4,3,2,

请输入广度优先遍历的开始结点:1

广度优先遍历序列是:1 5 2 4 3 Press any key to continue

3.扩展程序:

请输入图的类型(1:有向图 2:无向图 3:有向网 4:无向网):2

请输入顶点数,边数(逗号隔开):3,3

1个顶点的信息:

11

2个顶点的信息:

22

3个顶点的信息:

33

1条边的两个顶点的编号:(逗号隔开)1,2

2条边的两个顶点的编号:(逗号隔开)2,3

3条边的两个顶点的编号:(逗号隔开)3,1

 

请选择图的实现:

1__邻接矩阵

2__邻接表

3__深度优先搜索

4__广度优先搜索

5__最小生成树

6__拓扑排序

7__关键路径

8__从某个源点到其余各顶点的最短路径

9__每一对顶点之间的最短路径

10__退出......

1

邻接矩阵:

vertex     1   2   3

   1       0   1   1

   2       1   0   1

   3       1   1   0

 

请选择图的实现:

1__邻接矩阵

2__邻接表

3__深度优先搜索

4__广度优先搜索

5__最小生成树

6__拓扑排序

7__关键路径

8__从某个源点到其余各顶点的最短路径

9__每一对顶点之间的最短路径

10__退出......

3

请输入出发点编号:1

邻接表为:

[1,1]=>[3,0]-->[2,0]-->^

[2,2]=>[3,0]-->[1,0]-->^

[3,3]=>[1,0]-->[2,0]-->^

 

从第1点出发深度优先搜索遍历序列:   1->

请选择图的实现:

1__邻接矩阵

2__邻接表

3__深度优先搜索

4__广度优先搜索

5__最小生成树

6__拓扑排序

7__关键路径

8__从某个源点到其余各顶点的最短路径

9__每一对顶点之间的最短路径

10__退出......

4

请输入出发点编号:1

邻接表为:

[1,1]=>[3,0]-->[2,0]-->^

[2,2]=>[3,0]-->[1,0]-->^

[3,3]=>[1,0]-->[2,0]-->^

 

从第1点出发广度优先搜索遍历序列:

五、调试分析

调试中发现5个顶点6条边的无向图中

由于对称使得深度优先遍历和广度优先遍历都产生了

两种:即25对称的两种结果

对于算法来说调试有时候可以检验算法

使算法的精神得以驱动程序这个躯体

附加程序的调试最不简单原因是程序比较庞大

六、 源程序(带注释)

//程序1

#include <stdio.h>

#define n 5

#define MAXSIZE 10     //广度优先遍历时所使用的队列的最大容量

#define MaxNum 10000   //定义一个最大数

// 定义邻接矩阵类型

typedef int  adjmatrix[n+1][n+1];  // 0号单元没用

int visited[n+1];                  // 0号单元没用

int arcnum;                        //边的个数

//建立图的邻接矩阵

void CreatMatrix(adjmatrix GA)

{

int i,j,k;

  printf("图中有%d个顶点/n",n);

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

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

    if(i==j) GA[i][j]=0;     //对角线的值置为0

    else GA[i][j]=MaxNum;    //其它位置的值初始化为一个最大数

 printf("请输入边的个数(限制在110的范围内):");

 scanf("%d",&arcnum);

 printf("请输入图的所有边(一条边的两个端点中间用,分隔): , /n");

 for(k=1;k<=arcnum;k++)

     {scanf("%d,%d",&i,&j);     //读入边的信息

      GA[i][j]=1;             

      GA[j][i]=1;

     }

}

//从初始点v出发深度优先搜索邻接矩阵GA表示的图

void DfsMatrix(adjmatrix GA,int v)

{

     int j;

  visited[v]=1;  printf("%d,",v);

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

   if(v!=j&&GA[v][j]!=MaxNum&&!visited[j])

        DfsMatrix(GA,j);

}

//从初始点v出发广度优先搜索邻接矩阵GA表示的图

void BfsMatrix(adjmatrix GA,int v)

{

 int i,k,j,Q[MAXSIZE],front=0,rear=0;

 for(i=1;i<=n;i++) visited[i]=0;

 visited[v]=1;

 printf("%d ",v);

 rear=(rear+1)%MAXSIZE;                 //开始遍历的顶点入队列

 Q[rear]=v;

 while(front!=rear)

 {

  front=(front+1)%MAXSIZE;           //队头元素出队

  k=Q[front];

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

    if((!visited[j])&&(GA[k][j]==1))//访问与队头元素邻接的还未被访问的结点

     {

         visited[j]=1;          

        printf("%d ",j);

        rear=(rear+1)%MAXSIZE;

        Q[rear]=j;

    }//endif

 }//endwhile

}

void main()

{

  adjmatrix GA;

  int v;

  CreatMatrix(GA);

  printf("请输入深度优先遍历的开始结点:");

  scanf("%d",&v);

  printf("深度优先遍历序列是:");

  DfsMatrix(GA,v);

  printf("/n");

  printf("请输入广度优先遍历的开始结点:");

  scanf("%d",&v);

  printf("广度优先遍历序列是:");

  BfsMatrix(GA,v);

}

//程序2

#include <stdio.h>

#include <malloc.h>

#define MAXNODE 10

#define NULL 0

typedef struct arc

{

     int adjvex;

    struct arc *next;

}ArcNode;

typedef struct VexNode

{

     int vertex;

 ArcNode *firstarc;

}VerNode;

typedef VerNode AdjList[MAXNODE];

int visited[MAXNODE];

int vexnum,arcnum;

// 建立图的邻接表

void creatgraph(AdjList GL)

{

     int i,j,k;

    ArcNode *p;

    printf("请输入顶点个数和边的个数:");

    scanf("%d%d",&vexnum,&arcnum);

    printf("请输入顶点(顶点用整型数代表):/n");

 for(i=1;i<=vexnum;i++)

     {

        scanf("%d",&GL[i].vertex);

       GL[i].firstarc=NULL;

     }

 printf("请输入图的所有边(一条边的两个端点中间用,分隔): , /n");

 for(k=1;k<=arcnum;k++)

     {

        scanf("%d,%d",&i,&j);

       if(i&&j)

        {

            p=(ArcNode*)malloc(sizeof(ArcNode));

           p->adjvex=j;p->next=GL[i].firstarc;GL[i].firstarc=p;

           p=(ArcNode*)malloc(sizeof(ArcNode));

           p->adjvex=i;p->next=GL[j].firstarc; GL[j].firstarc=p;

        }

     }

 }

void dfs(AdjList G,int v)

{

     ArcNode *q;

  if(!visited[v])

       printf("%d,",G[v].vertex);

  visited[v]=1;

  q=G[v].firstarc;

  while(q!=NULL)

  {

       if(!visited[q->adjvex])

           dfs(G,q->adjvex);

      q=q->next;

  }

}

// 从初始点v出发深度优先遍历邻接表GL表示的图

void DfsAdjlist(AdjList GL,int v)

{

      int i;

 for(i=1;i<=vexnum;i++)

      visited[i]=0;

 if(!visited[v])

      dfs(GL,v);

}

//从初始点v出发广度优先遍历邻接表GL表示的图

void BfsAdjlist(AdjList GL,int v)

{

     int k,i,Q[MAXNODE],front=0,rear=0;

    ArcNode *p;

 for(i=1;i<=vexnum;i++)

      visited[i]=0;

 visited[v]=1;

 printf("%d ",GL[v].vertex);

 rear=(rear+1)%MAXNODE;

 Q[rear]=v;

 while(front!=rear)

 {

      front=(front+1)%MAXNODE;

     k=Q[front];

     p=GL[k].firstarc;

  while(p!=NULL)

    {

       if(!visited[p->adjvex])

       {

           visited[p->adjvex]=1;

          printf("%d ",p->adjvex);

          rear=(rear+1)%MAXNODE;

          Q[rear]=p->adjvex;

       }

      p=p->next;

    }

  }

}

void main()

{

  AdjList GL;

  int v;

  creatgraph(GL);

  printf("请输入深度优先遍历的开始结点:");

  scanf("%d",&v);

  printf("深度优先遍历序列是:");

  DfsAdjlist(GL,v);

  printf("/n");

  printf("请输入广度优先遍历的开始结点:");

  scanf("%d",&v);

  printf("广度优先遍历序列是:");

  BfsAdjlist(GL,v);

}

目录
相关文章
|
9月前
|
C++
C++程序设计实验4
C++程序设计实验4
75 0
|
9月前
|
Web App开发 存储 C++
C++程序设计实验5
C++程序设计实验5
48 0
|
9月前
|
机器学习/深度学习 Serverless C++
C++程序设计实验2
C++程序设计实验2
179 0
|
9月前
|
C++
C++程序设计实验1
C++程序设计实验1
64 0
|
9月前
|
C++
C++程序设计实验6
C++程序设计实验6
62 0
|
9月前
|
C++
C++程序设计实验8
C++程序设计实验8
66 0
|
弹性计算 网络协议 Linux
实验1 常用网络命令-1
实验1 常用网络命令-1
171 0
|
Scala
Scala编程实验三
Scala编程实验三
112 0
Scala编程实验三
|
缓存 Linux
我做了个实验!
这次我们就以 malloc 动态内存分配为切入点,我在文中也做了小实验: • malloc 是如何分配内存的? • malloc 分配的是物理内存吗? • malloc(1) 会分配多大的内存? • free 释放内存,会归还给操作系统吗? • free() 函数只传入一个内存地址,为什么能知道要释放多大的内存?
我做了个实验!