数据结构_图

本文介绍了图的基础知识,包括有向图与无向图的定义、术语以及分类。接着详细探讨了图的四种存储结构:邻接矩阵、邻接表、十字链表(有向图改进版)和邻接多重表(无向图改进版),分析了各自的存储思想、代码实现、优缺点,特别强调了这些结构在空间效率和操作便利性上的差异。
摘要由CSDN通过智能技术生成

图的基础

在线性表中,数据元素之间存在线性关系,每个元素存在前驱和后继结点;在树结构中,数据元素之间存在层次关系,并且一个结点可能和下一层次结点存在一对多的关系;而在图结构中,结点之间的关系可以是任意的,符合现实中很多事物之间的关系。

  1. 图的定义:图G=<V,E>(V vertex 顶点集,E edge 边集)。E可以为空,那时G只有顶点。
  2. 图的分类:有向图(边都为有向边)和无向图(边都为无向边)。<x,y>x为有向边起点,y为终点;<x,y>又称弧,x为弧尾,y为弧头。
  3. 图的术语(n,顶点数目;e,边的数目)
  1. 子图:G(V,E)和G1(V1,E1),V1和E1分别包含于V和E,称G1为G的子图。
  2. 无向完全图和有向完全图:无向图满足e=n*(n-1)/2(n的结点两两成边的组合);有向图满足e=n*(n-1)(n的结点两两成边的排列)
  3. 权和网:边带边权值,可以表示为两个顶点的距离或消耗。这样带权的图被称为网
  4. 邻接点:无向图G,存在边<v,v1>,那么v和v1互为邻接点,边和这俩顶点相关联。
  5. 度、出度和入度:顶点的度为与该顶点相关联的边的数目。入度为该顶点为弧头的边的数目,相对应,出度为顶点为弧尾的边的数目。e为各顶点度的和的1/2。
  6. 路径和路径长度:一个顶点到另一个顶点经过的顶点序列。路径长度为路径上边或弧的数目。
  7. 回路或环:路径中第一个顶点和最后一个顶点相同。
  8. 简单路径、简单环:路径中不存在重复顶点。
  9. 连通:顶点v到v1存在路径。
  10. 无图中从每一个顶点到另一个顶点都存在路径被称为连通图。若整个图不满足但是极大连通子图满足,被称为连通分量;若为有向图,称为强连通图。类似的,满足的条件的极大连通子图被称为强连通分量。
  11. 连通图的生成树:一个极小连通子图,含有全部n的顶点,和足以构成一棵树的n-1个边。如下图表示的一颗生成树。
    在这里插入图片描述
  1. 有向树和生成森林:有一个顶点入度为0,其他顶点的入度都为1的有向图被称为有向树。一个有向图的生成树由若干树组成。
    ~如图左边的有向图和右边的生成树
    在这里插入图片描述

图的存储结构

邻接矩阵

存储思想

因为图的任意两个顶点之间可能存在关系,所以一个G含有n个顶点,可以用n阶矩阵来表示顶点之间邻接关系,也称邻接矩阵。

如果图中存在<i,j>这条弧:

  1. 如果是有向图,致矩阵aij = 1,否则为0;
  2. 同理可知无向图的矩阵为对称矩阵,aij = aji = 1;
  3. 若是网,那么致aij = wij ,否则为无穷大。

下图为有向网的邻接矩阵
在这里插入图片描述

代码

邻接矩阵的实现采用,一个顶点集,一个边集来存储表示。

///GAmatrix.h
#pragma once
#include<stdio.h>
#define Maxint 32767
#define MAX 10  

//类型定义
typedef char VertexType;
typedef int Edgetype;

//邻接表定义
typedef struct {
   
	VertexType V[MAX];           //顶点集
	Edgetype E[MAX][MAX];        //边集
	int n, e;
}G_Amatreix;

//创建图
void CreateG(G_Amatreix& g);

//找到顶点在顶点集中的标号
int LocateV(G_Amatreix g, VertexType v);

函数实现

#include<stdio.h>
#include"GAmatrix.h"

/// ===============================================
/// 图接口实现
/// ===============================================
//创建图
void CreateG(G_Amatreix& g) {
   
	printf("input n , e:\n");
	scanf_s("%d,%d", &g.n, &g.e);
	getchar();
	//初始化V
	for (int i = 0; i < g.n; ++i) {
   
		printf("input V[%d]:", i);
		scanf_s("%c", &g.V[i], 1);
		char ch = getchar();
		while (ch != '\n')
			ch = getchar();
	}
	//初始化E
	for (int i = 0; i < g.n; ++i) {
   
		for (int j = 0; j < g.n; ++j) {
   
			g.E[i][j] = Maxint;                   //创立网是为无穷大,图时为0
		}
	}
	//输入边
	char v1 = 0, v2 = 0;
	int m = 0;;
	int j, k;
	for (int i = 0; i < g.e; ++i) {
   
		printf("input the edge:(v1 v2 w)\n");
		scanf_s("%c %c %d", &v1, 1, &v2, 1, &m);
		char ch = getchar();
		while (ch != '\n')
			ch = getchar();
		j = LocateV(g, v1);
		k = LocateV(g, v2); 
		g.E[j][k] = m;                      //创立网时为权值w,图时为1
		g.E[k][j]=g.E[j][k];                 //无向时为对称矩阵

	}


	//输出边
	for (int i = 0; i < g.n; ++i) {
   
		printf("顶点%c:\n", g.V[i]);
		for (int j = 0; j < g.n; ++j) {
   
			if (g.E[i][j] != Maxint)
				printf("边为<%c,%c>,权值为%d:\n", g.V[i], g.V[j], g.E[i][j])
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值