数据结构学习—图

图的定义

图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。

关于图的各种定义

  • 无向边:若顶点 v i v_{i} vi v j v_{j} vj之间的边没有方向,则称这条边为无向边(Edge)。
  • 无向图:若图中任意两个顶点之间的边都是无向边,则称该图为无向图。如果任意两个顶点都存在边,则称该图为无向完全图。含有n个顶点的完全无向图有n(n-1)/2条边。
  • 有向边:若顶点 v i v_{i} vi v j v_{j} vj之间的边有方向,则称这条边为有向边,也称为弧(Arc)。用有序偶< v i v_{i} vi v j v_{j} vj>, v i v_{i} vi表示头, v j v_{j} vj表示尾。
  • 有向图:如果图中任意两个顶点之间的边都是有向边,则称该图为有向图。如果任意两个顶点都存在方向互为相反的边,则称该图为有向完全图。含有n个顶点的有向完全图有n(n-1)条边。

图的表示

邻接矩阵

在这里插入图片描述

邻接矩阵优点

  • 方便检查任意一对顶点间是否存在边
  • 方便查找任一顶点的所有“邻接点”
  • 方面计算任一顶点的“度”

邻接矩阵缺点

  • 浪费时间(统计稀疏图中一共有多少边)
  • 浪费空间(点很多,边很少)

邻接表

邻接表优点

  • 方便查找任一顶点的邻接点
  • 节约稀疏图的空间,需要N个头指针+2E个节点

邻接表缺点

  • 不方面检查任意一对顶点是否存在边
  • 对有向图只能计算出度;需要构造“逆邻接表”来计算入度

邻接矩阵建图

#include <stdio.h>
#include <stdlib.h>
#include "io.h"
#include "math.h"
#include "time.h"

#define ERROR 0
#define OK 1
#define FALSE 0
#define TRUE 1
#define MAXVEX 20
#define INFINITY 65535

typedef char VertexType;
typedef int Status;
typedef int EdgeType;

//定义图的结构
typedef struct {
    VertexType vexs[MAXVEX];
    EdgeType arc[MAXVEX][MAXVEX];
    int numNode,numEdge;
}Mgraph;
//建立无向网图
void CreatMgraph(Mgraph *G)
{
    int i, j, k, W;
    printf("请输入顶点数和边数: \n");
    scanf("%d,%d",&G->numNode,&G->numEdge);
    for(i=0; i<G->numNode; i++){
        printf("请输入第%d个顶点\n",i+1);
        scanf("%c\n",&G->vexs[i]);
    } //输入顶点
    for(j=0; j<G->numNode; j++)
        for(k=0; k<G->numNode; k++){
            G->arc[j][k] = INFINITY;
        } //初始化图
    for(k=0; k<G->numEdge; k++){
        printf("输入Vi,Vj的下标i,j和权值W");
        scanf("%d%d%d",&i,&j,&W);
        G->arc[i][j] = W;
        G->arc[j][i] = W;
    }//设置边的权值
}

int main()
{
    Mgraph G;
    CreatMgraph(&G);
    return 0;
}

邻接表建图

#include <stdio.h>
#include <stdlib.h>
#include "io.h"
#include "math.h"
#include "time.h"

#define ERROR 0
#define OK 1
#define FALSE 0
#define TRUE 1
#define MAXVEX 20
#define INFINITY 65535

typedef int VertexType;
typedef int Status;
typedef int EdgeType;

typedef struct EdgeNode  //定义边表节点
{
    int vex;   //节点下标
    EdgeType W; //边的权值
    struct EdgeNode *Next;
}EdgeNode;

typedef struct VertexNode  //定义顶点表节点
{
    VertexType data;
    EdgeNode *first;

}VertexNode, VerList[MAXVEX];;

typedef struct
{
    VerList verList;
    int numEdge,numNode;
}Lgraph; //定义图结构

void CreateLgraph(Lgraph *G)
{
    int i, j, k;
    EdgeNode *e;
    printf("输入节点数和边数:\n");
    scanf("%d,%d",&G->numNode,&G->numEdge);
    for(i=0; i<G->numNode; i++){
        scanf("%d",&G->verList[i].data);
        G->verList->first = NULL;
    }//输入顶点,初始化边节点

    for(k=0; k<G->numEdge; k++){
        printf("输入边(vi,vj)上的顶点序号:\n");
        scanf("%d,%d",&i,&j);
        e = (EdgeNode*)malloc(sizeof(EdgeNode)); //新建一个边节点
        e->vex = j;
        e->Next = G->verList[i].first;
        G->verList[i].first = e;

        e = (EdgeNode*)malloc(sizeof(EdgeNode));
        e->vex = i;
        e->Next = G->verList[j].first;
        G->verList[j].first = e;
    }
}

int main()
{
    Lgraph G;
    CreateLgraph(&G);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值