图的表示与遍历
邻接矩阵,邻接表以及深度优先搜索,广度优先搜索
1.邻接矩阵
typedef struct Graph* graph;
//邻接矩阵结构表示
struct Graph {
//datatype data[maxsize];//当顶点具有其他意义时
int dot;//顶点数
int line;//边数
int map[maxsize][maxsize];
};
//所插入的边结构表示
typedef struct linenode* edge;
struct linenode {
int dot1, dot2;
//int wight;//当定义有权图时使用,用来存储权
};
//初始化具有n个节点没有边的图
graph create(int dotnum) {
graph g;
int i, j;
g = (graph)malloc(sizeof(struct Graph));
g->dot = dotnum;
g->line = 0;
for (i = 0; i < g->dot; i++) {
for (j = 0; j < g->dot; j++) {
g->map[i][j] = 0;//当两个点的边不存在时设为0
}
}
return g;
}
//插入边数
void insert(graph g,edge e){
//g->map[e->dot1][e->dot2] = e->wight;//有权重时
//g->map[e->dot2][e->dot1] = e->wight;//当为无向图时需定义两边
g->map[e->dot1][e->dot2] = 1;//无权重时
g->map[e->dot2][e->dot1] = 1;
}
//建造图
graph bulidgraph() {
int dotnum;
printf("请输入所建图所需的点数");
scanf_s("%d", &dotnum);//读入所建图的点数
graph g = create(dotnum);
printf("请输入所建图的边数");
scanf_s("%d", &g->line);//读入边数
if (g->line != 0) {
edge e=(edge)malloc(sizeof(struct linenode));
for (int i = 0; i < g->line; i++) {
//printf("添加边,请输入第一个点,第二个点,以及权重");
//scanf_s("%d%d%d", &e->dot1, &e->dot2, &e->wight);
printf("添加边,请输入第一个点,第二个点");
scanf_s("%d%d", &e->dot1, &e->dot2);
insert(g, e);
}
}
return g;
}
邻接表,主要用于稀疏矩阵
//所插入的边结构表示
typedef struct linenode* edge;
struct linenode {
int dot1, dot2;
//int wight;//当定义有权图时使用,用来存储权
};
//链表结构,每个节点包含该点的位置以及一个指针
typedef struct ln* linenode;
struct ln {
int dot;//该弧所指向顶点的位置
//int weight;//有权图
linenode next;//指向下一条弧的指针
};
//邻接表结构,用存储链表的数组实现,包含第一个节点的信息
typedef struct Vnode {
linenode firstedge;//第一条依附该顶点的弧指针
//data data;//若顶点还需要存储其他数据
}Adjlist[maxsize];
//图的邻接表表示结构
typedef struct AList* list;
struct AList {
int dots;//图所含点数
int lines;//图所含边数
Adjlist G;//邻接表
};
//初始化邻接表
list createlist(int dotnum) {
list g;
g = (list)malloc(sizeof(struct AList));
g->dots = dotnum;
g->lines = 0;
for (int i = 0; i < dotnum; i++) {
g->G[i].firstedge = NULL;//将所有链表都设为空
}
return g;
}
void insertlist(list g, edge e) {
//有向图
//linenode l=(linenode)malloc(sizeof(struct Vnode));
//l->dot = e->dot2;
//l->next = g->G[e->dot1].firstedge;
//g->G[e->dot1].firstedge = l;
//g->G[e->dot1].firstedge->weight=weight//若有权重
//无向图
linenode l = (linenode)malloc(sizeof(struct Vnode));
l->dot = e->dot2;
l->next = g->G[e->dot1].firstedge;
g->G[e->dot1].firstedge = l;//插入在第一个节点处
l = (linenode)malloc(sizeof(struct Vnode));
l->dot = e->dot1;
l->next = g->G[e->dot2].firstedge;
g->G[e->dot2].firstedge = l;
}
list buildlist() {
printf("请输入图所含的点数");
int dotnum;
edge e=(edge)malloc(sizeof(struct linenode));
scanf_s("%d", &dotnum);
list l = createlist(dotnum);
printf("请输入图所含的边数");
scanf_s("%d",&l->lines);
if (l->lines != 0) {
for (int i = 0; i < l->lines; i++) {
printf("请输入第一个点,第二个点");
scanf_s("%d%d", &e->dot1, &e->dot2);
insertlist(l, e);
}
}
return l;
}
3.图的遍历
1.DFS,深度优先搜索
邻接表的深度优先搜索
邻接表的深度优先搜索
void DFS(list l, int x,int* visited) {
printf("正在遍历第%d个节点",x);
linenode w = l->G[x].firstedge;
visited[x] = 1;
while (w) {
if (!visited[w->dot]) DFS(l, w->dot,visited);
w = w->next;
}
}
void DFStraverse(list l) {//邻接表所存储的图,从x为出发点对图进行DFS深度优先搜索
int visited[maxsize];//由于C语言没有布尔类型,用0表示未被访问,1表示该节点已被访问
for (int i = 0; i < l->dots; i++) visited[i] = 0;
for (int i = 0; i < l->dots; i++) {
if (!visited[i]) DFS(l, i,visited);
}
}
2.邻接表的广度优先 搜索,利用队列进行
void BFStraverse(list l) {
int visited[maxsize];//由于C语言没有布尔类型,用0表示未被访问,1表示该节点已被访问
for (int i = 0; i < l->dots; i++) visited[i] = 0;//把所有节点设为未访问
quene s = createquene();
for (int i = 0; i < l->dots; i++) {
if (!visited[i]) {//遍历所有节点,若已被遍历则i+1
visited[i] = 1; //若没遍历则把该节点设为以遍历
printf("正在遍历第%d个节点",i);
insertquene(s, i);//将i插入队列
while (!isempty(s)) {
int u = deletex(s);//弹出最先入队列的元素u
linenode w = l->G[u].firstedge;//找到u对应的链表头节点
while (w) {
if (!visited[w->dot]){//把u对应的所有节点都遍历并插入队列
visited[w->dot] = 1;//表示该节点以遍历
printf("正在遍历第%d个节点", w->dot);
insertquene(s, w->dot);
w = w->next;
}
}
}
}
}
}
邻接矩阵的深度优先搜索
//邻接矩阵的深度优先搜索
void DFS(graph l, int* visited, int x) {
visited[x] = 1;
printf("正在访问%d节点",x);
for (int j = 0; j < l->dot; j++) {
if (!visited[j] && l->map[x][j] == 1)//当节点未被访问并且i,j有边
DFS(l, visited, j);
}
}
void DFStraverse(graph l) {
int visited[maxsize];//由于C语言没有布尔类型,用0表示未被访问,1表示该节点已被访问
for (int i = 0; i < l->dot; i++) visited[i] = 0;
for(int i = 0; i < l->dot;i++) {
if (!visited[i]) {
DFS(l, visited, i);
}
}
}
邻接矩阵的广度优先搜索
void BFStraverse(graph l) {
int visited[Maxsize];
quene q = createquene();
for (int i = 0; i < l->dot; i++) visited[i] = 0;
for (int i = 0; i < l->dot; i++) {
if (!visited[i]) {
visited[i] = 1;
insertquene(q, i);
printf("正在访问%d个节点", i);
while (!isempty(q)) {
int z = deletex(q);
for (int j = 0; j < l->dot; j++) {
if (!visited[j] && l->map[z][j] == 1) {
insertquene(q, j);
visited[j] = 1;
printf("正在访问%d个节点", j);
}
}
}
}
}
}
&spm=1001.2101.3001.5002&articleId=107594486&d=1&t=3&u=605709c2a69a4f23b0b85c657251d0a3)
887

被折叠的 条评论
为什么被折叠?



