c语言实现基本数据结构(图)
图是基本的数据结构中比较复杂的了,相对于链表一类来说。因为忘了不少,于是参考了一下书上的代码。
(ps:感觉第一个难点是不知道怎么命名变量名…… ╮(╯▽╰)╭ )
图的表示方法有四种, 分别是
- 邻接矩阵表示法
- 邻接表表示法
- 十字链表表示法
- 临界多重表表示法
我只写了邻接表表示法和十字链表表示法。第一个很简单,最后一个不经常用。
下面是邻接表表示法的结构体
/*
*邻接表表示法的结构体
*/
struct ArcNode{//边节点
int adjvex;//该条边的头节点在数组中的位置
struct ArcNode* nextarc;//与该条边的头节点的下一条边相连
};
struct VertexNode{//头节点
char* nodeinfo;//节点信息|名字
struct ArcNode* nextarc;//与该头节点相连的第一个边结点
};
typedef struct {//邻接表表示法的图结构
struct VertexNode vertex[MAX];
int vernum, arcnum;//节点数量和弧的数量
GraphKind kind;//图的种类
}AdjList;
十字链表表示法的结构体
/*
*十字链表表示法的结构体
*/
typedef struct OrthArcNode{//弧节点
int headvex;//该弧出发的节点
int tailvex;//该弧结束的节点
struct OrthArcNode* hlink;//该弧出发的节点的下一条节点
struct OrthArcNode* tlink;//该弧结束的节点的下一条节点
}OrthArcNode;
typedef struct OrthVertexNode{//头节点
char* nodeinfo;//节点的信息|名字
struct OrthArcNode* firstin, *firstout;/*以该节点为出发点的第一条弧和以该节点为结束点的第一条弧*/
}OrthVertexNode;
typedef struct{//十字链表表示法的结构体
OrthVertexNode vertex[MAX];
int vernum, arcnum;//节点数量和弧的数量
GraphKind kind;//图的种类
} OrthList;
方法有创建图和深度遍历图,深度遍历只有十字链表的,因为感觉相似就只写了一个:)
完整代码如下
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
#define True 1
#define False 0
#define Error -1
#define OK 1
int visited[MAX];
typedef enum{DG, DN, UDG, UDN} GraphKind;
/*
*邻接表表示法的结构体
*/
struct ArcNode{//边节点
int adjvex;//该条边的头节点在数组中的位置
struct ArcNode* nextarc;//与该条边的头节点的下一条边相连
};
struct VertexNode{//头节点
char* nodeinfo;//节点信息|名字
struct ArcNode* nextarc;//与该头节点相连的第一个边结点
};
typedef struct {//邻接表表示法的图结构
struct VertexNode vertex[MAX];
int vernum, arcnum;//节点数量和弧的数量
GraphKind kind;//图的种类
}AdjList;
/*
*十字链表表示法的结构体
*/
typedef struct OrthArcNode{//弧节点
int headvex;//该弧出发的节点
int tailvex;//该弧结束的节点
struct OrthArcNode* hlink;//该弧出发的节点的下一条节点
struct OrthArcNode* tlink;//该弧结束的节点的下一条节点
}OrthArcNode;
typedef struct OrthVertexNode{//头节点
char* nodeinfo;//节点的信息|名字
struct OrthArcNode* firstin, *firstout;/*以该节点为出发点的第一条弧和以该节点为结束点的第一条弧*/
}OrthVertexNode;
typedef struct{//十字链表表示法的结构体
OrthVertexNode vertex[MAX];
int vernum, arcnum;//节点数量和弧的数量
GraphKind kind;//图的种类
} OrthList;
//创建一个邻接表表示法的图
void CreateAdjGraph(AdjList * g, int len){
char* var;
int temp, i = 0, j = 0;
g->vernum = 0;
g->arcnum = 0;
for(int i = 0; i < len; i++){
var = (char*)malloc(10);
scanf("%s", var);
struct VertexNode node = {var, NULL};
g->vertex[i] = node;
g->vernum++;
}
while(i != -1){
printf("please input arc-head\n");
scanf("%d", &i);
printf("please input arc-tail\n");
scanf("%d", &temp);
if(i > len || temp > len){
printf("crossed!please re-enter\n ");
continue;
}
struct ArcNode * arcnode = {temp, g->vertex[i].nextarc};
g->vertex[i].nextarc = arcnode;
g->arcnum++;
}
}
//创建一个十字链表表示法的图
void CreateOrthGraph(OrthList *g, int len){
char* var;
int temp, i, j;
g->vernum = 0;
g->arcnum = 0;
for(int i = 0; i < len; i++){
var = (char*)malloc(10);
scanf("%s", var);
OrthVertexNode node = {var, NULL, NULL};
g->vertex[i] = node;
g->vernum++;
}
while(i != -1){
printf("please input arc-head\n");
scanf("%d", &i);
printf("please input arc-tail\n");
scanf("%d", &j);
if(i >= len || j >= len){
printf("crossed!please re-enter\n ");
continue;
}
if( i == -1){
break;
}
OrthArcNode * arcnode = (OrthArcNode *)malloc(sizeof(OrthArcNode));
arcnode->tailvex = j;
arcnode->headvex = i;
arcnode->tlink = g->vertex[j].firstout;
g->vertex[j].firstout = arcnode;
arcnode->hlink = g->vertex[i].firstin;
g->vertex[i].firstin = arcnode;
g->arcnum++;
}
}
//输出十字链表表示法的节点的信息|名称
void PrintVer(OrthVertexNode vertex){
printf("%s ", vertex.nodeinfo);
};
void DepthFirstSearchOrth(OrthList *g, int index,void (*visit)(OrthVertexNode vertex)){
visit(g->vertex[index]);
visited[index] = True;
OrthArcNode *p = g->vertex[index].firstin;
while(p != NULL){
if(!visited[p->tailvex]) DepthFirstSearchOrth(g, p->tailvex, visit);
p = p->hlink;
}
}
//深度遍历十字链表表示法的图
void TraverseOrthGraph(OrthList *g, int len,void (*visit)(OrthVertexNode vertex)){
for(int i = 0; i< len; i++){
visited[i] = False;
}
for(int i = 0; i< len; i++){
if(!visited[i]) DepthFirstSearchOrth(g, i, visit);
}
}
未完待续