最近在复习数据结构
今天把图的一些数据结构重写了遍
现在拿出来给大家分享 也是能记录我复习的一个过程
中间有错误的地方请大家指出
我们知道图有好几种分法,
当然最重要的一种就是有向图和无向图
这里主要介绍下无向图的数据结构
这里推荐2中方式的数据结构
一个是邻接矩阵一个是邻接表
邻接矩阵就是用矩阵来存放图, 2点间有边的在矩阵中就为1 否则为0
而邻接表其实是用链式的方式,把每一个点做为链头,然后把和他有关连的点连在一个链中
这里邻接矩阵是唯一的表示 而邻接表的表示不唯一.
#include
<
stdio.h
>
#include < stdlib.h >
#define MAX 100
typedef struct // 邻接图每个点的结构
{
int no; // 点的编号
int info; // 点的信息 假定为一个数,在这里程序中暂不使用
}Vertex;
typedef struct // 邻接图的结构
{
int edges[MAX][MAX]; // 邻接图
int vernum,arcnum; // 顶点数和弧数
Vertex vers[MAX]; // 每个点的内容 点的信息,暂不使用
}MGraph;
void CreateMGraph(MGraph *& m, int map[][ 3 ], int ver, int arc) // 由输入来建立邻接图
{
m = (MGraph * )malloc( sizeof (MGraph));
m -> arcnum = arc;
m -> vernum = ver;
int i,j;
for (i = 0 ;i < ver;i ++ )
for (j = 0 ;j < ver;j ++ )
m -> edges[i][j] = 0 ;
for (i = 0 ;i < arc;i ++ )
{
m -> edges[map[i][ 0 ]][map[i][ 1 ]] = 1 ;
m -> edges[map[i][ 1 ]][map[i][ 0 ]] = 1 ;
}
for (i = 0 ;i < ver;i ++ )
{
for (j = 0 ;j < ver;j ++ )
printf( " %d " ,m -> edges[i][j]);
printf( " " );
}
return ;
}
typedef struct ANode // 邻接表 每个节点的结构
{
int adjvex; // 该点的编号
struct ANode * next; // 指向下个点
int info;
}Arcnode;
typedef struct Vnode // 每个点的邻接表
{
Vertex * data; // 起始点的结构
Arcnode * firstart; // 起始点后的节点
}VNode;
// typedef VNode AdjList[MAX];
typedef struct // 邻接表的结构
{
VNode * adjlist[MAX]; // 由每个邻接点的邻接表构成一个大的邻接表
int ver,arc; // VER是点的个数, ARC是边的个数
}ALGraph;
void CreateALGraph(ALGraph *& m, int map[][ 3 ], int ver, int arc) // 由输入来建立邻接表
{
int i,j;
int a,b;
m = (ALGraph * )malloc( sizeof (ALGraph));
m -> ver = ver;
m -> arc = arc;
for (i = 0 ;i < ver;i ++ )
{
VNode * g;
g = (VNode * )malloc( sizeof (Vnode)); // 这里我本想用g->firstart=NULL好象这样不行 可书上是这样写
g -> firstart = NULL; // 最后还是这样写比较好点
m -> adjlist[i] = g;
}
for (i = 0 ;i < arc;i ++ )
{
for (j = 0 ;j < 2 ;j ++ )
{
if (j == 0 )
{
a = map[i][ 0 ];
b = map[i][ 1 ];
}
else // 这里是为了建立表时 使无向图的两个顶点都能建立相对的节点
{
a = map[i][ 1 ];
b = map[i][ 0 ];
}
m -> adjlist[a] -> data -> no = a;
VNode * q;
q = (VNode * )malloc( sizeof (VNode));
Arcnode * p;
p = (Arcnode * )malloc( sizeof (Arcnode));
q = m -> adjlist[a];
if (q -> firstart == NULL)
{
p -> adjvex = b;
p -> next = NULL;
q -> firstart = p;
}
else
{
p = q -> firstart;
while (p -> next != NULL)
p = p -> next;
Arcnode * k;
k = (Arcnode * )malloc( sizeof (Arcnode));
k -> adjvex = b;
k -> next = NULL;
p -> next = k;
}
}
}
Arcnode * z;
z = (Arcnode * )malloc( sizeof (Arcnode));
for (i = 0 ;i < ver;i ++ )
{
printf( " !!%d " ,m -> adjlist[i] -> data -> no);
z = m -> adjlist[i] -> firstart;
while (z != NULL)
{
printf( " --->%d " ,z -> adjvex);
z = z -> next;
}
printf( " " );
}
return ;
}
void MtoL(MGraph * m,ALGraph *& g) // 这里是邻接图转邻接表的过程
{ // 这个包括下面的邻接表转邻接图的过程 都可以转成他们自己建立的过程
int i,j; // 这里专门写他们直接转换, 而不是通过转换成一个数组,是为了学习的原因
int ver,arc;
g = (ALGraph * )malloc( sizeof (ALGraph));
ver = m -> vernum;
arc = m -> arcnum;
for (i = 0 ;i < ver;i ++ )
{
VNode * p;
p = (VNode * )malloc( sizeof (VNode));
p -> firstart = NULL;
g -> adjlist[i] = p;
}
for (i = 0 ;i < ver;i ++ )
{
g -> adjlist[i] -> data -> no = i;
for (j = 0 ;j < ver;j ++ )
{
if (m -> edges[i][j] != 0 )
{
VNode * p;
p = (VNode * )malloc( sizeof (VNode));
Arcnode * q;
q = (Arcnode * )malloc( sizeof (Arcnode));
p = g -> adjlist[i];
if (p -> firstart == NULL)
{
q -> adjvex = j;
q -> next = NULL;
p -> firstart = q;
}
else
{
q = p -> firstart;
while (q -> next != NULL)
q = q -> next;
Arcnode * z;
z = (Arcnode * )malloc( sizeof (Arcnode));
z -> adjvex = j;
z -> next = NULL;
q -> next = z;
}
}
}
}
Arcnode * k;
k = (Arcnode * )malloc( sizeof (Arcnode));
for (i = 0 ;i < ver;i ++ )
{
printf( " !!%d " ,g -> adjlist[i] -> data -> no);
k = g -> adjlist[i] -> firstart;
while (k != NULL)
{
printf( " --->%d " ,k -> adjvex);
k = k -> next;
}
printf( " " );
}
}
void LtoM(MGraph *& m,ALGraph * g) // 邻接表转邻接图
{
int i,j,ver,arc;
int k;
ver = g -> ver;
arc = g -> arc;
m = (MGraph * )malloc( sizeof (MGraph));
for (i = 0 ;i < ver;i ++ )
for (j = 0 ;j < ver;j ++ )
m -> edges[i][j] = 0 ;
for (i = 0 ;i < ver;i ++ )
{
Arcnode * p;
p = g -> adjlist[i] -> firstart;
while (p != NULL)
{
k = p -> adjvex;
p = p -> next;
m -> edges[i][k] = 1 ;
}
}
for (i = 0 ;i < ver;i ++ )
{
for (j = 0 ;j < ver;j ++ )
printf( " %d " ,m -> edges[i][j]);
printf( " " );
}
}
int main()
{
MGraph * m;
ALGraph * am;
int map[MAX][ 3 ];
int i,j;
int ver,arc;
printf( " input ver arc " );
scanf( " %d%d " , & ver, & arc); // 输入 图有多少点 和多少 边
for (i = 0 ;i < arc;i ++ )
scanf( " %d %d " , & map[i][ 0 ], & map[i][ 1 ]); // 把有连线的点输进来, 中间要有空格
/* //这里可以根据不同需要选用不同函数
CreateMGraph(m,map,ver,arc);
CreateALGraph(am,map,ver,arc);
MtoL(m,am);
LtoM(m,am);
*/
return 0 ;
}
#include < stdlib.h >
#define MAX 100
typedef struct // 邻接图每个点的结构
{
int no; // 点的编号
int info; // 点的信息 假定为一个数,在这里程序中暂不使用
}Vertex;
typedef struct // 邻接图的结构
{
int edges[MAX][MAX]; // 邻接图
int vernum,arcnum; // 顶点数和弧数
Vertex vers[MAX]; // 每个点的内容 点的信息,暂不使用
}MGraph;
void CreateMGraph(MGraph *& m, int map[][ 3 ], int ver, int arc) // 由输入来建立邻接图
{
m = (MGraph * )malloc( sizeof (MGraph));
m -> arcnum = arc;
m -> vernum = ver;
int i,j;
for (i = 0 ;i < ver;i ++ )
for (j = 0 ;j < ver;j ++ )
m -> edges[i][j] = 0 ;
for (i = 0 ;i < arc;i ++ )
{
m -> edges[map[i][ 0 ]][map[i][ 1 ]] = 1 ;
m -> edges[map[i][ 1 ]][map[i][ 0 ]] = 1 ;
}
for (i = 0 ;i < ver;i ++ )
{
for (j = 0 ;j < ver;j ++ )
printf( " %d " ,m -> edges[i][j]);
printf( " " );
}
return ;
}
typedef struct ANode // 邻接表 每个节点的结构
{
int adjvex; // 该点的编号
struct ANode * next; // 指向下个点
int info;
}Arcnode;
typedef struct Vnode // 每个点的邻接表
{
Vertex * data; // 起始点的结构
Arcnode * firstart; // 起始点后的节点
}VNode;
// typedef VNode AdjList[MAX];
typedef struct // 邻接表的结构
{
VNode * adjlist[MAX]; // 由每个邻接点的邻接表构成一个大的邻接表
int ver,arc; // VER是点的个数, ARC是边的个数
}ALGraph;
void CreateALGraph(ALGraph *& m, int map[][ 3 ], int ver, int arc) // 由输入来建立邻接表
{
int i,j;
int a,b;
m = (ALGraph * )malloc( sizeof (ALGraph));
m -> ver = ver;
m -> arc = arc;
for (i = 0 ;i < ver;i ++ )
{
VNode * g;
g = (VNode * )malloc( sizeof (Vnode)); // 这里我本想用g->firstart=NULL好象这样不行 可书上是这样写
g -> firstart = NULL; // 最后还是这样写比较好点
m -> adjlist[i] = g;
}
for (i = 0 ;i < arc;i ++ )
{
for (j = 0 ;j < 2 ;j ++ )
{
if (j == 0 )
{
a = map[i][ 0 ];
b = map[i][ 1 ];
}
else // 这里是为了建立表时 使无向图的两个顶点都能建立相对的节点
{
a = map[i][ 1 ];
b = map[i][ 0 ];
}
m -> adjlist[a] -> data -> no = a;
VNode * q;
q = (VNode * )malloc( sizeof (VNode));
Arcnode * p;
p = (Arcnode * )malloc( sizeof (Arcnode));
q = m -> adjlist[a];
if (q -> firstart == NULL)
{
p -> adjvex = b;
p -> next = NULL;
q -> firstart = p;
}
else
{
p = q -> firstart;
while (p -> next != NULL)
p = p -> next;
Arcnode * k;
k = (Arcnode * )malloc( sizeof (Arcnode));
k -> adjvex = b;
k -> next = NULL;
p -> next = k;
}
}
}
Arcnode * z;
z = (Arcnode * )malloc( sizeof (Arcnode));
for (i = 0 ;i < ver;i ++ )
{
printf( " !!%d " ,m -> adjlist[i] -> data -> no);
z = m -> adjlist[i] -> firstart;
while (z != NULL)
{
printf( " --->%d " ,z -> adjvex);
z = z -> next;
}
printf( " " );
}
return ;
}
void MtoL(MGraph * m,ALGraph *& g) // 这里是邻接图转邻接表的过程
{ // 这个包括下面的邻接表转邻接图的过程 都可以转成他们自己建立的过程
int i,j; // 这里专门写他们直接转换, 而不是通过转换成一个数组,是为了学习的原因
int ver,arc;
g = (ALGraph * )malloc( sizeof (ALGraph));
ver = m -> vernum;
arc = m -> arcnum;
for (i = 0 ;i < ver;i ++ )
{
VNode * p;
p = (VNode * )malloc( sizeof (VNode));
p -> firstart = NULL;
g -> adjlist[i] = p;
}
for (i = 0 ;i < ver;i ++ )
{
g -> adjlist[i] -> data -> no = i;
for (j = 0 ;j < ver;j ++ )
{
if (m -> edges[i][j] != 0 )
{
VNode * p;
p = (VNode * )malloc( sizeof (VNode));
Arcnode * q;
q = (Arcnode * )malloc( sizeof (Arcnode));
p = g -> adjlist[i];
if (p -> firstart == NULL)
{
q -> adjvex = j;
q -> next = NULL;
p -> firstart = q;
}
else
{
q = p -> firstart;
while (q -> next != NULL)
q = q -> next;
Arcnode * z;
z = (Arcnode * )malloc( sizeof (Arcnode));
z -> adjvex = j;
z -> next = NULL;
q -> next = z;
}
}
}
}
Arcnode * k;
k = (Arcnode * )malloc( sizeof (Arcnode));
for (i = 0 ;i < ver;i ++ )
{
printf( " !!%d " ,g -> adjlist[i] -> data -> no);
k = g -> adjlist[i] -> firstart;
while (k != NULL)
{
printf( " --->%d " ,k -> adjvex);
k = k -> next;
}
printf( " " );
}
}
void LtoM(MGraph *& m,ALGraph * g) // 邻接表转邻接图
{
int i,j,ver,arc;
int k;
ver = g -> ver;
arc = g -> arc;
m = (MGraph * )malloc( sizeof (MGraph));
for (i = 0 ;i < ver;i ++ )
for (j = 0 ;j < ver;j ++ )
m -> edges[i][j] = 0 ;
for (i = 0 ;i < ver;i ++ )
{
Arcnode * p;
p = g -> adjlist[i] -> firstart;
while (p != NULL)
{
k = p -> adjvex;
p = p -> next;
m -> edges[i][k] = 1 ;
}
}
for (i = 0 ;i < ver;i ++ )
{
for (j = 0 ;j < ver;j ++ )
printf( " %d " ,m -> edges[i][j]);
printf( " " );
}
}
int main()
{
MGraph * m;
ALGraph * am;
int map[MAX][ 3 ];
int i,j;
int ver,arc;
printf( " input ver arc " );
scanf( " %d%d " , & ver, & arc); // 输入 图有多少点 和多少 边
for (i = 0 ;i < arc;i ++ )
scanf( " %d %d " , & map[i][ 0 ], & map[i][ 1 ]); // 把有连线的点输进来, 中间要有空格
/* //这里可以根据不同需要选用不同函数
CreateMGraph(m,map,ver,arc);
CreateALGraph(am,map,ver,arc);
MtoL(m,am);
LtoM(m,am);
*/
return 0 ;
}
关与图的存储结构就先写到这
慢慢会上传更多的关于数据结构的程序