标签:
转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51888031
图的存储方法有邻接表、邻近矩阵、邻接多重表、十字链表等。本篇文章介绍两种简单且比较常用的两种方法:邻接表与邻接矩阵方法。
以下面的无向图为例,介绍两种存储方法。有向图的存储方法类似,只是边是单方向,无向图的边可以看做双向。
邻接链表表示法对图中的每个顶点建立一个带头的边链表;第i条链表代表依附于顶点
所有表头结点以顺序结构的形式存储,以便可以随机访问任一顶点的边链表。上图的邻接链表表示法如下:
存储空间:
对于有n个顶点,e条边的无向图而言,需要n个表头结点和2e个边链表结点。
度、出度和入度:
无向图顶点度的概念是依附于该结点的边的个数。从边链表表示法中可以很容易的计算顶点的度,即对应边链表结点的个数。
有向图顶点的出度是以该顶点为弧尾的弧的个数。同理,入度是以该顶点为弧头的弧的个数。在邻接链表表示法中,有向图顶点的出度为对应边链表结点的数目。有向图顶点的入度计算比较复杂,必须要遍历整个邻接链表才能得出结果。一种解决方法是再建立一个逆邻接表法,或者采用十字链表法。
代码
/************************************************************************
CSDN 勿在浮沙筑高台 http://blog.csdn.net/luoshixian099算法导论--图的存储(邻接链表)2016年7月12日
************************************************************************/
#include <iostream>
using namespace std;
typedef struct VertexNode //链表表头结点
{
char data;
struct ArcNode * firstarc;//指向第一条边
}VertexNode;
typedef struct ArcNode //边链表结点
{
char data;
struct ArcNode * nextarc;//指向下一条边
}ArcNode;
ArcNode * InSertArcNode(char name) //新建边结点,待插入到边链表中
{
ArcNode * p = new ArcNode;
p->data = name;
p->nextarc = NULL;
return p;
}
VertexNode * AdjList()//邻接链表表示法
{
ArcNode * p=NULL;
VertexNode * List_head = new VertexNode[9]; //顺序存储表头结点
int count = 0;
List_head[count].data = ‘A‘;
p = List_head[count].firstarc = InSertArcNode(‘B‘);
p = p->nextarc = InSertArcNode(‘D‘);
p = p->nextarc = InSertArcNode(‘E‘);
count++;
List_head[count].data = ‘B‘;
p = List_head[count].firstarc = InSertArcNode(‘A‘);
p = p->nextarc = InSertArcNode(‘C‘);
p = p->nextarc = InSertArcNode(‘E‘);
count++;
List_head[count].data = ‘C‘;
p = List_head[count].firstarc = InSertArcNode(‘B‘);
p = p->nextarc = InSertArcNode(‘F‘);
count++;
List_head[count].data = ‘D‘;
p = List_head[count].firstarc = InSertArcNode(‘A‘);
p = p->nextarc = InSertArcNode(‘G‘);
count++;
List_head[count].data = ‘E‘;
p = List_head[count].firstarc = InSertArcNode(‘A‘);
p = p->nextarc = InSertArcNode(‘B‘);
p = p->nextarc = InSertArcNode(‘G‘);
count++;
List_head[count].data = ‘F‘;
p = List_head[count].firstarc = InSertArcNode(‘C‘);
count++;
List_head[count].data = ‘G‘;
p = List_head[count].firstarc = InSertArcNode(‘D‘);
p = p->nextarc = InSertArcNode(‘E‘);
p = p->nextarc = InSertArcNode(‘H‘);
count++;
List_head[count].data = ‘H‘;
p = List_head[count].firstarc = InSertArcNode(‘G‘);
p = p->nextarc = InSertArcNode(‘I‘);
count++;
List_head[count].data = ‘I‘;
p = List_head[count].firstarc = InSertArcNode(‘H‘);
return List_head;
}
int main()
{
char vextex[] = { ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘, ‘I‘ };
VertexNode * GRAPH = AdjList(); //创建图--邻接链表
ArcNode *p = NULL;
for (int i = 0; i < 9;i++) //输出
{
cout << GRAPH[i].data << ": ";
p = GRAPH[i].firstarc;
while (p != NULL)
{
cout << p->data << ",";
p = p->nextarc;
}
cout << endl;
}
return 0;
}
对于包含n个顶点的图,建立一个n×n的矩阵arc;用arc[i][j]的取值表示弧
矩阵中第i行表示图的顶点
对于无权图而言,若弧存在则对应元素为1,否则为0;有权图而言,弧存在即为弧的权重,否则为无穷大;
最开始的无向无权图的邻接矩阵表示法如下:
存储空间:
对于无向图而言,邻接矩阵为一个对称矩阵,我们只需要存储矩阵下三角即可,因此对于包含n个顶点的图,只需要
度、出度与入度:
针对无权图:
无向图顶点的度,即为第i行的所有元素和。
有向图顶点的出度,即为第i行的所有元素和;入度为第i列的所有元素和。
代码:
/************************************************************************
CSDN 勿在浮沙筑高台 http://blog.csdn.net/luoshixian099算法导论--图的存储(邻接矩阵)2016年7月12日
************************************************************************/
#include <iostream>
using namespace std;
void AdjMatrix(char arc[][9])
{
for (int i = 0; i < 9; i++) //初始化邻接矩阵
for (int j = 0; j < 9; j++)
{
arc[i][j] = 0;
}
arc[0][1] = arc[0][3] = arc[0][4] = 1;
arc[1][0] = arc[1][2] = arc[1][4] = 1;
arc[2][1] = arc[2][5] = 1;
arc[3][0] = arc[3][6] = 1;
arc[4][0] = arc[4][1] = arc[4][6] = 1;
arc[5][2] = 1;
arc[6][3] = arc[6][4] = arc[6][7] = 1;
arc[7][6] = arc[7][8] = 1;
arc[8][7] = 1;
}
int main()
{
char vextex[] = { ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘, ‘I‘ };
char arc[9][9] = { 0 };
AdjMatrix(arc);
for (int i = 0; i < 9; i++)
{
cout << vextex[i] << ": ";
for (int j = 0; j < 9; j++)
{
if (arc[i][j]==1)
{
cout << vextex[j] << ",";
}
}
cout << endl;
}
return 0;
}
Reference:
数据结构-耿国华
标签:
原文地址:http://blog.csdn.net/luoshixian099/article/details/51888031