数据结构之图(C/C++实现)

图的定义:

这里面的术语很多:
具体的定义请参考这篇文章:
https://segmentfault.com/a/1190000013223267

图的存储结构

邻接矩阵

图的邻接矩阵存储结构代码:

typedef char VertexType;  //结点类型
typedef int EdgeType;   //边上的权值类型
#define MAXVEX 100    //最大顶点数
#define INFINITY 65535   //用65535来代替无穷大
typedef struct
{
    VertexType vexs[MAXVEX];   //顶点表
    EdgeType arc[MAXVEX][MAXVEX];   //邻接矩阵,可看作表
    int numVertexes,numEdges;    //图中当前的顶点数和边数
}MGraph;

无向网图的邻接矩阵表示代码

void CreateMGraph(MGraph *G)
{
    int row,col,value;
    std::cout<<"请输入顶点数和边数"<<std::endl;
    std::cin>>G->numVertexes>>G->numEdges;
    std::cout<<"读入顶点信息,建立顶点表"<<std::endl;
    for(int i=0;i<G->numVertexes;i++)   //读入顶点信息,建立顶点表
    {
        std::cin>>G->vexs[i];
    }
    //邻接矩阵初始化
    for(int i=0;i<G->numVertexes;i++)
    {
        for(int j=0;j<G->numVertexes;j++)
        {
            G->arc[i][j]=INFINITY;
        }
    }
    for(int k=0;k<G->numEdges;k++)
    {
        std::cout<<"输入边(Vi,Vj)上的下标i,下标j和权w:"<<std::endl;
        std::cin>>row>>col>>value;
        G->arc[row][col]=value;
        G->arc[col][row]=G->arc[row][col];    //因为是无向图,所以矩阵对称
    }
}

从代码可以看出,对于n个顶点和e条边的无向网图创建,时间复杂度为O(n+n2+e),其中对邻接矩阵的初始化耗费了O(n2)的时间。

邻接表

邻接矩阵是一种不错的图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费。

我们把数组与链表相结合的存储方法称为邻接表(Adjacency List)
邻接表结构代码

typedef char VertexType;  //结点类型
typedef int EdgeType;   //边上的权值类型

typedef struct EdgeNode   //边表节点
{
    int adjvex;     //邻接点域,存储该顶点对应的下标
    EdgeType weight;   //用于存储权值,对于非网图可以不需要
    struct EdgeNode *next;   //链域,指向下一个邻接点
}EdgeNode;

typedef struct VertexNode   //顶点表结点
{
    VertexType data;   //顶点域,存储顶点信息
    EdgeNode *firstedge;   //边表头指针
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes,numEdges;   //图中当前的顶点数和边数
}GraphAdjList;

邻接表的创建代码

void CreateALGraph(GraphAdjList *G)
{
    int row,col;
    EdgeNode *e;
    std::cout<<"输入顶点数和边数"<<std::endl;
    std::cin>>G->numVertexes>>G->numEdges;
    //读入顶点信息,建立顶点表
    for(int i=0;i<G->numVertexes;i++)
    {
        std::cin>>G->adjList[i].data;  //输入顶点信息
        G->adjList[i].firstedge=nullptr;  //将边表置为空表
    }
    //建立边表
    for(int i=0;i<G->numEdges;i++)
    {
        std::cout<<"输入边(Vi,Vj)上的顶点序号:"<<std::endl;
        std::cin>>row>>col;
        e=(EdgeNode *)malloc(sizeof (EdgeNode));
        e->adjvex=col;
        e->next=G->adjList[row].firstedge;
        G->adjList[row].firstedge=e;
        
        e=(EdgeNode *)malloc(sizeof (EdgeNode));
        e->adjvex=row;
        e->next=G->adjList[col].firstedge;
        G->adjList[col].firstedge=e;
    }
}

十字链表

邻接多重表

具体参考这篇文章
https://segmentfault.com/a/1190000015188957

图的遍历

深度优先遍历

邻接矩阵形式的深度优先遍历

typedef int Boolean;
Boolean visited[MAXSIZE];   //访问标志的数组
/*邻接矩阵的深度优先递归算法*/
void DFS(MGraph G,int i)
{
    int j;
    visited[i]=True;
    std::cout<<G.vexs[i]<<std::endl;
    for(j=0;j<G.numVertexes;j++)
    {
        if(G.arc[i][j]==1&&!visited[j])
        {
            DFS(G,j);
        }
    }
}
/*邻接矩阵的深度遍历操作*/
void DFSTraverse(MGraph G)
{
    int i;
    for(i=0;i<G.numVertexes;i++)
    {
        visited[i]=False;   //初始化所有顶点状态都是未访问过的顶点
    }
    for(i=0;i<G.numVertexes;i++)
    {
        if(!visited[i])   //对未访问的顶点调用DFS,若是连通图,只会执行一次
            DFS(G,i);
    }
}

邻接表的深度优先遍历

/*邻接表的深度优先递归算法*/
void DFS(GraphAdjList GL,int i)
{
    EdgeNode *p;
    visited[i]=True;
    std::cout<<GL.adjList[i].data<<std::endl;  //打印顶点,也可以是其他操作
    p=GL.adjList[i].firstedge;
    while (p)
    {
        if(!visited[p->adjvex])
        {
            DFS(GL,p->adjvex);    //对未访问的邻接顶点递归调用
        }
        p=p->next;
    }
}
/*邻接表的深度遍历操作*/
void DFSTraverse(GraphAdjList GL)
{
    int i;
    for(i=0;i<GL.numVertexes;i++)
    {
        visited[i]=False;  //初始化所有顶点状态都是未访问的状态
    }
    for(i=0;i<GL.numVertexes;i++)
    {
        if(!visited[i])   //对未访问的顶点调用DFS,若是连通图,只会执行一次
            DFS(GL,i);
    }
}

邻接矩阵的时间复杂度O(N2)
邻接表的时间复杂度O(N+e)

广度优先遍历

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构课程设计c/c++版--美团餐馆预定信息的管理与分析。 本课程设计旨在设计一个C/C++程序,用于管理和分析美团餐馆的预定信息。通过合理的数据结构设计和算法编程,实现对餐馆的预定信息进行管理和分析,以提高用户的预定体验和餐馆的效益。 首先,需要设计合适的数据结构来存储餐馆的预定信息。可以利用链表、数组、队列等数据结构来存储餐馆的基本信息(如名称、地址、电话等)和预定信息(如预定日期、预定时间、预定人数等)。通过数据结构的合理选择和设计,能够提高程序的运行效率和数据的访问速度。 其次,需要设计相应的功能模块来管理餐馆的预定信息。包括添加餐馆信息、查询餐馆信息、预定餐馆、取消预定等功能。通过各个功能模块之间的有机组合和调用,能够实现对预定信息的全面管理和操作。 最后,需要设计一些算法来进行预定信息的分析。可以通过统计预定信息的频次、根据用户的偏好推荐适合的餐馆等方法,对预定信息进行分析和挖掘。这样可以从大量的数据中挖掘出有价值的信息,进一步提高餐馆的运营策略和用户的预定体验。 通过本课程设计,不仅能够提高学生对数据结构的理解和应用能力,还能够锻炼学生的问题分析和解决能力。同时,也能够为美团等餐饮平台提供有价值的参考和借鉴。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值