复杂数据结构(四)图

图的遍历

广度优先遍历类似于树的按层次遍历,具体过程如下:
(1)从数组中选择一个未被访问的顶点Vi,将其标记为已访问。
(2)接着依次访问Vi的所有未被访问的邻接点,并标记为已被访问过。
(3)从这些邻接点出发进行广度优先遍历,直至图中所有和Vi有路径相通的顶点都被访问过。
(4)重复步骤(1)至步骤(3)的操作,直至所有顶点都被访问过。

图(f)采用广度优先搜索遍历以V0为出发点的顶点序列为:V0,V1,V3,V4,V2,V6,V8,V5,V7

 

深度优先遍历方法类似于树的先序遍历,具体过程如下:
(1)从数组中选择一个未被访的顶点Vi,将其标记为已访问。
(2)接着从Vi的一个未被访问过的邻接点出发进行深度优先遍历。
(3)重复步骤(2),直至图中所有和Vi有路径相通的顶点都被访问过。
(4)重复步骤(1)至步骤(3)的操作,直至所有顶点都被访问过。

红色数字代表遍历的先后顺序,所以图(e)无向图的深度优先遍历的顶点访问序列为:V0,V1,V2,V5,V4,V6,V3,V7,V8

程序编写<GraphTrav>:

#include <stdio.h>
#include "AdjMatrixGraph.c"//之前邻接矩阵保存图法时编写的
#define QUEUE_MAXSIZE 30 //队列的最大容量
typedef struct
{
    int Data[QUEUE_MAXSIZE]; //数据域
    int head; //队头指针
    int tail; //队尾指针
}SeqQueue; //队列结构
//队列操作函数
void QueueInit(SeqQueue *q); //初始化一个队列
int QueueIsEmpty(SeqQueue q); //判断队列是否空
int QueueIn(SeqQueue *q,int n); //将一个元素入队列
int QueueOut(SeqQueue *q,int *ch); //将一个元素出队列  

//图操作函数
void DFSTraverse(MatrixGraph *G); //深度优先遍历
void BFSTraverse(MatrixGraph *G); //广度优先遍历
void DFSM(MatrixGraph *G,int i);
void BFSM(MatrixGraph *G,int i);

void QueueInit(SeqQueue *Q)    //队列初始化
{
    Q->head=Q->tail=0;
}
int QueueIsEmpty(SeqQueue Q)   //判断队列是否已空,若空返回1,否则返回0
{
    return Q.head==Q.tail;
}
int QueueIn(SeqQueue *Q,int ch)   //入队列,成功返回1,失败返回0
{
    if((Q->tail+1) % QUEUE_MAXSIZE ==Q->head) //若队列已满
        return 0;  //返回错误;
    Q->Data[Q->tail]=ch; //将数据ch入队列
    Q->tail=(Q->tail+1) % QUEUE_MAXSIZE; //调整队尾指针
    return 1; //成功,返回1
}
int QueueOut(SeqQueue *Q,int *ch)   //出队列,成功返回1,并用ch返回该元素值,失败返回0
{
    if(Q->head==Q->tail) //若队列为空
        return 0; //返回错误
    *ch=Q->Data[Q->head]; //返回队首元素
    Q->head=(Q->head+1) % QUEUE_MAXSIZE; //调整队首指针
    return 1; //成功出队列,返回1
}   

void DFSTraverse(MatrixGraph *G) //深度优先遍历
{
    int i;
    for(i=0;i<G->VertexNum;i++) //清除各顶点遍历标志
        G->isTrav[i]=0;
    printf("深度优先遍历结点:");
    for(i=0;i<G->VertexNum;i++)
        if(!G->isTrav[i]) //若该点未遍历
            DFSM(G,i); //调用函数遍历
    printf("\n"); 

}
void DFSM(MatrixGraph *G,int i) //从第i个结点开始,深度遍历图
{
    int j;
    G->isTrav[i]=1; //标记该顶点已处理过
    printf("->%c",G->Vertex[i]);//输出结点数据
//    printf("%d->",i); //输出结点序号 

    //添加处理节点的操作
    for(j=0;j<G->VertexNum;j++)
        if(G->Edges[i][j]!=MAXVALUE && !G->isTrav[i])
            DFSM(G,j); //递归进行遍历
}
void BFSTraverse(MatrixGraph *G) //广度优先
{
    int i;
    for (i=0;i<G->VertexNum;i++) //清除各顶点遍历标志
        G->isTrav[i]=0;
    printf("广度优先遍历结点:");
    for (i=0;i<G->VertexNum;i++)
        if (!G->isTrav[i])
            BFSM(G,i);
    printf("\n");
}
void BFSM(MatrixGraph *G,int k) //广度优先遍历
{
    int i,j;
    SeqQueue Q; //创建循环队列
    QueueInit(&Q); //初始化循环队列 

    G->isTrav[k]=1; //标记该顶点
    printf("->%c",G->Vertex[k]);  //输出第一个顶点 

    //添加处理节点的操作
    QueueIn(&Q,k); //入队列
    while (!QueueIsEmpty(Q)) //队列不为空
    {
        QueueOut(&Q,&i); //出队列
        for (j=0;j<G->VertexNum;j++)
            if(G->Edges[i][j]!=MAXVALUE && !G->isTrav[j])
            {
                printf("->%c",G->Vertex[j]);
                G->isTrav[j]=1;  //标记该顶点
                //处理顶点
                QueueIn(&Q,j); //出队列
            }
    }
}

事件:

#include <stdio.h>
#include "GraphTrav.c"
int main()
{
    MatrixGraph G; //定义保存邻接表结构的图
    int path[VERTEX_MAX];
    int i,j,s,t;
    char select;
    do
    {
        printf("输入生成图的类型(0:无向图,1:有向图):");
        scanf("%d",&G.GraphType); //图的种类
        printf("输入图的顶点数量和边数量:");
        scanf("%d,%d",&G.VertexNum,&G.EdgeNum); //输入图顶点数和边数
        for(i=0;i<G.VertexNum;i++)  //清空矩阵
            for(j=0;j<G.VertexNum;j++)
                G.Edges[i][j]=MAXVALUE; //设置矩阵中各元素的值为0
        CreateMatrixGraph(&G); //生成邻接表结构的图
        printf("邻接矩阵数据如下:\n");
        OutMatrix(&G); //输出邻接矩阵
        DFSTraverse(&G); //深度优先搜索遍历图
        BFSTraverse(&G); //广度优先搜索遍历图
        printf("图遍历完毕,继续进行吗?(Y/N)");
        scanf(" %c",&select);
    }while(select!=‘N‘ && select!=‘n‘);
    getch();
    return 0;
}

结果:

时间: 2024-10-09 05:53:02

复杂数据结构(四)图的相关文章

数据结构实验报告-实验四 图的构造与遍历

实验四   图的构造与遍历   l  实验目的 1.图的的定义和遍历 (1)掌握图的邻接矩阵.邻接表的表示方法. (2)掌握建立图的邻接矩阵的算法. (3)掌握建立图的邻接表的算法. (4)加深对图的理解,逐步培养解决实际问题的能力. l  实验内容 1.图的定义和遍历 (一)基础题 1.编写图基本操作函数: (1)CreateALGraph(ALGraph &G) 建立无向图的邻接表表示: (2)LocateVex(ALGraph &G,char v)图查找信息: (3)DFSTrave

2017-2018-1 20162330 实验四 图的实现与应用

课程名称:<程序设计与数据结构> 学生班级:1623班 学生姓名:刘伟康 学生学号:20162330 实验时间:2017年11月20日-2017年11月24日 实验名称:图的实现与应用 指导老师:娄嘉鹏.王志强老师 目录 实验要求 实验步骤及代码实现 代码托管汇总 图的实现与应用-1:用邻接矩阵实现无向图 图的实现与应用-2:用十字链表实现有向图 图的实现与应用-3:实现PP19.9 测试过程及遇到的问题 1. 第一个实验无向图的边输入错误 分析总结及PSP时间统计 参考资料 实验要求: 实验

20162327WJH实验四——图的实现与应用

20162327WJH实验四--图的实现与应用 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验日期:11月20日 实验密级: 非密级 预习程度: 已预习 实验时间:15:25-17:15 必修/选修: 必修 实验序号: cs_23 实验内容 实验一 1.实验内容 用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,

数据结构:图的实现--邻接矩阵

图结构的邻接矩阵实现 为了表现图中顶点之间的关联,我们可以使用邻接矩阵来实现图结构.所谓的邻接矩阵,就是一个反应边与边之间联系的二维数组.这个二维数组我们用matrix[numV][numV]表示,其中numV是顶点数. 对于无权图 若顶点Vi和Vj之间有边,则matrix[Vi][Vj]=1;否则matrix[Vi][Vj]=0. 对于有权图 若顶点Vi和Vj之间有边,且权值为weight,则matrix[Vi][Vj]=weight;否则matrix[Vi][Vj]=0或MAXWEIGHT(

数据结构之图 Part2 - 1

邻接矩阵 网上很少有C# 写图的数据结构的例子,实际的项目中也从来没用过Array 这坨东西,随手写个,勿喷. namespace LH.GraphConsole { public struct Graph { public Graph(int vertexNumber, int edgeNumber) { VertexNumber = vertexNumber; EdgeNumber = edgeNumber; Vertexs = new string[VertexNumber]; Edges

数据结构之图 Part1

Part 1 预计使用7天的时间来过掉图相关的数据结构.第一天主要是一天图的基本概念,熟练掌握定义是一切交流和沟通的基础. 1定义 1.1图 有穷非空顶点,外加边. G(V,E) Graph Vertex Edge 顶点就是 点,有穷非空. 顶点之间的关系就是边,边可空. 1.2 分类 无向边:无方向的边. 有向边:有方向的边,弧. 简单图:无重复边和自己到自己的顶点. 带权的图称为网. 无向图的度:顶点的边数. 有向图的度:顶点的弧的数量分为入度和出度. 连通图:任意两点有路径. 生成树:无向

数据结构:图--拓扑排序

拓扑排序 拓扑排序 在实际应用中,有向图的边可以看做是顶点之间制约关系的描述.把顶点看作是一个个任务,则对于有向边<Vi,Vj>表明任务Vj的完成需等到任务Vi完成之后,也就是说任务Vi先于任务Vj完成.对于一个有向图,找出一个顶点序列,且序列满足:若顶点Vi和Vj之间有一条边<Vi,Vj>,则在此序列中顶点Vi必在顶点Vj之前.这样的一个序列就称为有向图的拓扑序列(topological order). 步骤 从有向图中选取一个没有前驱(入度为0)的顶点输出. 删除图中所有以它为

数据结构:图的实现--邻接表

使用邻接表实现图结构 当图中的边数较少时,用邻接表来实现图结构,则会浪费很多内存空间.因此,考虑另一种实现图结构的方法:邻接表.在邻接表中主要有两种节点结构体: 顶点节点 边节点 直接看代码 类定义 #include<iostream> #include<iomanip> using namespace std; //最大权值 #define MAXWEIGHT 100 //边节点 typedef struct edgenode_tag { int adjvex; //邻接点 in

【算法与数据结构】图 -- 邻接表

/************************************************************************ 边(弧)结点 -------------------------- |adjvex | info | nextarc | -------------------------- adjvex:邻接点域,该点在图中的位置 info :相关信息,比如可以保存从某顶点到该点的权值 nextac:指向下一个与该点有相同邻接点的顶点 顶点结点 ---------

浅谈算法和数据结构: 四 快速排序

原文:浅谈算法和数据结构: 四 快速排序 上篇文章介绍了时间复杂度为O(nlgn)的合并排序,本篇文章介绍时间复杂度同样为O(nlgn)但是排序速度比合并排序更快的快速排序(Quick Sort). 快速排序是20世纪科技领域的十大算法之一 ,他由C. A. R. Hoare于1960年提出的一种划分交换排序. 快速排序也是一种采用分治法解决问题的一个典型应用.在很多编程语言中,对数组,列表进行的非稳定排序在内部实现中都使用的是快速排序.而且快速排序在面试中经常会遇到. 本文首先介绍快速排序的思