一步一步写算法(之图结构)

原文:一步一步写算法(之图结构)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

     图是数据结构里面的重要一章。通过图,我们可以判断两个点之间是不是具有连通性;通过图,我们还可以计算两个点之间的最小距离是多少;通过图,我们还可以根据不同的要求,寻找不同的合适路径。当然,有的时候为了计算的需要,我们还需要从图中抽象出最小生成树,这样在遍历计算的时候就不需要持续判断是不是遇到了循环节点。当然,这所有的一切都是从图的表示开始的。

    1)矩阵表示

    矩阵表示可以说是最简单的表示方法,如果说一个图中有5个点,那么我们就可以构建一个5*5的矩阵。如果点和点之间存在连接,那么填上1;反之如果不存在连接,那么可以用0表示,当然对角线上面的点是没有意义的。如下图所示:

static int graph[5][5] =
{
	{0, 1, 0, 1, 1},
	{1, 0, 1, 0, 1},
	{0, 1, 0, 1, 0},
	{1, 0, 1, 0, 1},
	{1, 1, 0, 1, 0}
};

    如果点和点之间还是存在方向的,那么它们关于(x,x)对称轴就是不对称的,所以结果也可能是这样的:

static int graph[5][5] =
{
	{0, 0, 0, 0, 0},
	{1, 0, 0, 0, 0},
	{0, 1, 0, 0, 0},
	{1, 0, 1, 0, 0},
	{1, 1, 0, 1, 0}
};

    当然,如果点和点之间的关系存在某种权重,比如说距离,那我们可以用它来代替原来的数据1:

static int graph[5][5] =
{
	{0, 0, 0, 0, 0},
	{3, 0, 0, 0, 0},
	{0, 6, 0, 0, 0},
	{8, 0, 4, 0, 0},
	{9, 2, 0, 7, 0}
};

    矩阵表示下的图结构非常直观。但是,矩阵有一个特点,就是比较浪费空间。因为我们这里举例的顶点比较少,只有5个,但是请大家试想一下,如果一张图上有10000个节点,那么10000*10000该是多大的一个空间啊。重要的是,这10000*10000上面大多数点都是0,所以浪费的空间是相当可观的。

    2)数组结构

    为了改变矩阵浪费空间的特点,我们可以建立一个只有顶点和边组成的数据空间。比如说,我们定义一个这样的结构:

typedef struct _LINE
{
	int start;
	int end;
	int weight;
	int isDirection;
}LINE;

    上面定义的数据结构非常简洁。第1个为起始顶点,第2个为终点,第3个为权重,第4个判断当前边是否有向。图中要是有多少边,我们就要定义多少个这样的数据。如果把这些边的数据都放在一起构成一个数组,那么我们就可以用这个数组来表示图的全部信息了。

    但是,我们还是觉得有遗憾的地方。这个数据结构过分强调了边的意义和重要性,忽略了顶点本身的含义。因为,我们在强调边的时候,应该添加进顶点的相关特性。离开顶点的支持,单纯的边信息是没有什么含义的。

    3)基于顶点链表的图表示

    首先,我们定义顶点的基本结构:

typedef struct _LINE
{
	int end;
	int weight;
	struct _LINE* next;
}LINE;

typedef struct _VECTEX
{
	int start;
	int number;
	LINE* neighbor;
}VECTEX;

    我们用VECTEX记录顶点的相关信息,LINE表示节点的相关信息。如果LINE是在VECTEX中的变量,那么neighbor表示当前所有节点的起始点都是start点。如果它是PATH中的变量呢,那么next的起始点就是LINE链接的前面一个点,不知道我讲清楚了没有?下面就是点与点之间PATH的定义。

typedef struct _PATH
{
	int start;
	int end;
	int lenth;
	LINE* next;
}PATH;

    其中start为起始点,end为终结点,next为start链接的下一个点,lenth为路径的总长度,当然也可以修改成其他的权重形式。

注意事项:

    1)数组和链表是图结构的基础,朋友们应该好好掌握

    2)每一种数据结构都有自己的应用场合,关键是理解其中的思想和方法

    3)图的表示是图运算的基础,掌握它们是我们进一步学习的基本条件

时间: 2024-09-14 06:13:21

一步一步写算法(之图结构)的相关文章

一步一步写算法(之图的保存)

原文:一步一步写算法(之图的保存) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面的几篇博客,我们对图进行基本定义,同时介绍了图的创建.图的添加和删除等.今天,我们聊一聊图是怎么在存储在外设中的.这些外接设备可以是各种类型的,比如说,可以是硬盘.sd卡.网络硬盘等等.本质上说,我们今天讨论的主题就是怎么把图的数据永久地保留在本地.并且,如果需要加载这些数据,也可以快速恢复图原来的面貌.对图数据结构已经记得不太清楚的朋友可以复

一步一步写算法(之图创建)

原文:一步一步写算法(之图创建) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们讨论过图的基本结构是什么样的.它可以是矩阵类型的.数组类型的,当然也可以使指针类型的.当然,就我个人而言,比较习惯使用的结构还是链表指针类型的.本质上,一幅图就是由很多节点构成的,每一个节点上面有很多的分支,仅此而已.为此,我们又对原来的结构做了小的改变: typedef struct _LINE { int end; int weight;

一步一步写算法(之图添加和删除)

原文:一步一步写算法(之图添加和删除) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们谈到的图的数据结构.图的创建,今天我们就来说一说如何在图中添加和删除边.边的添加和删除并不复杂,但是关键有一点需要记住,那就是一定要在小函数的基础之上构建大函数,否则很容易出现错误.     一.边的创建     边的创建一般来说可以分为下面以下几个步骤:     1)判断当前图中是否有节点,如果没有,那么在pGraph->head处添

一步一步写算法(之 算法总结)

原文:一步一步写算法(之 算法总结) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]       自10月初编写算法系列的博客以来,陆陆续续以来写了几十篇.按照计划,还有三个部分的内容没有介绍,主要是(Dijkstra算法.二叉平衡树.红黑树).这部分会在后面的博客补充完整.这里主要是做一个总结,有兴趣的朋友可以好好看看,欢迎大家提出宝贵意见.       (1) 排序算法     快速排序           合并排序     堆排序

一步一步写算法(之哈希二叉树)

原文:一步一步写算法(之哈希二叉树) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     用过平衡二叉树的朋友都清楚,平衡二叉树的最大优点就是排序.不管是在数据插入的时候还是在数据删除的时候,我们都要考虑到数据的排序情况.但是和数据的添加.删除一样重要的,还有数据的查询.很不幸,平衡二叉树经常由于节点的添加和删除,数据的查询效率会变得非常低下.朋友们可以看看下面这样的一个极端场景,所有分支节点都只有一边存在数据: /* * 7 3 *

一步一步写算法(之克鲁斯卡尔算法 上)

原文:一步一步写算法(之克鲁斯卡尔算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     克鲁斯卡尔算法是计算最小生成树的一种算法.和prim算法(上,中,下)按照节点进行查找的方法不一样,克鲁斯卡尔算法是按照具体的线段进行的.现在我们假设一个图有m个节点,n条边.首先,我们需要把m个节点看成m个独立的生成树,并且把n条边按照从小到大的数据进行排列.在n条边中,我们依次取出其中的每一条边,如果发现边的两个节点分别位于两棵树上,

一步一步写算法(之prim算法 上)

原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们讨论了图的创建.添加.删除和保存等问题.今天我们将继续讨论图的一些其他问题,比如说如何在图的环境下构建最小生成树.为什么要构建最小生成树呢?其实原理很简单.打个比方,现在某一个乡镇有n个村,那么这n个村肯定是联通的.现在我们打算在各个村之间搭建网线,实现村村通的工程.那么有什么办法可以实现村村互通,同时又使得最后的总距离最小呢?要达

一步一步写算法(之 A*算法)

原文:一步一步写算法(之 A*算法) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     在前面的博客当中,其实我们已经讨论过寻路的算法.不过,当时的示例图中,可选的路径是唯一的.我们挑选一个算法,就是说要把这个唯一的路径选出来,怎么选呢?当时我们就是采用穷尽递归的算法.然而,今天的情形有点不太一样了.在什么地方呢?那就是今天的路径有n条,这条路径都可以达到目的地,然而我们在挑选的过程中有一个要求,那就是挑选的路径距离最短?有没有什么

一步一步写算法(之函数堆栈显示)

原文:一步一步写算法(之函数堆栈显示) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com ]     在继续图的讨论之前,我们今天开个小差,讨论一下函数堆栈的基本原理.有过编程经验的朋友都知道,堆栈调试是我们在程序开发中经常应用的一个功能.那么大家有没有想过,函数堆栈是怎么开始的啊?其实我们可以自己写一个函数堆栈输出函数分析一下.     因为一般来说,函数的压栈过程是这样的:               |    参数三  |