连通集(浙大数据结构习题)
#include<stdio.h>
#include <stdlib.h>
#define maxsize 10
#define false 0
#define true 1
typedef int vertex; //顶点下标
typedef int weighttype;
//图的邻接表建立
//1.图的节点 边,邻接表节点 头结点指针数组 图
typedef struct edgenode *edge;
struct edgenode {
/*边,通过输入边来构建图*/
vertex v1, v2;
//weighttype weight; //权重
};
typedef struct advnode *pvnode; /*邻接表的邻接点链节点*/
struct advnode
{
vertex v;
//weighttype weight;
pvnode next;
};
typedef struct vnode {
//表头
pvnode firstnode;
//int data; //非必须
}vlist[maxsize]; //邻接表
typedef struct gnode *Lgraph; //图
struct gnode {
int N;
int E;
vlist Glist;
};
//2.图的建立 初始化 插入边 建立图
Lgraph create(int vnum,int edgenum) {
Lgraph g = (Lgraph)malloc(sizeof(struct gnode));
g->N = vnum;
g->E = edgenum; //建立有vnum个顶点的图
for (int i = 0; i < vnum; i++) {
g->Glist[i].firstnode = NULL; //初始化表头指针为空
}
return g;
}
int insert(int n, pvnode *q) {
pvnode temp = (pvnode)malloc(sizeof(struct advnode));
temp->v = n;
temp->next = NULL;
pvnode current; //记录前面的指针
pvnode previous = NULL;
current = *q;
while (current != NULL && current->v < n) {
//找到比n大的结点,把n插在前面 找到或者current==NULL
previous = current;
current = current->next;
}
temp->next = current;
if (previous == NULL) *q = temp;
else previous->next = temp;
return true;
}
void insertgraph(Lgraph g, edge e) {
insert(e->v2, &(g->Glist[e->v1].firstnode));
insert(e->v1, &(g->Glist[e->v2].firstnode));
}
Lgraph buildgraph() {
Lgraph g;
int nv, ne;
scanf("%d %d", &nv, &ne);
g = create(nv,ne); //初始化图
//输入边
if(ne!=0){
edge e = (edge)malloc(sizeof(struct edgenode)); //边只是起到输入的作用因此在for循环建立结点即可
for(int i=0;i<ne;i++){
scanf("%d %d", &e->v1, &e->v2);
insertgraph(g, e);
}
}
return g;
}
//3.节点访问函数
int initiate(int visit[]) {
for (int i = 0; i < maxsize; i++) visit[i] = false;
return true;
}
void visitnode(int v) {
printf("%d ", v);
}
//4.深度优先遍历
void DFS(Lgraph g,int v,int visit[]) {
visitnode(v);
visit[v] = true; //访问v
pvnode w;
for (w = g->Glist[v].firstnode; w; w = w->next) {
//v的所有邻接点进栈
if(!visit[w->v]) DFS(g, w->v, visit); //w2=w->firstnode 深度优先遍历
}
}
//5.队列 结点 队头队尾指针 初始化 插入删除
typedef struct lnode *list;
struct lnode {
int data;
list nextnode;
};
struct qnode {
list front, gear;
int Maxsize;
};
typedef struct qnode *qlist;
qlist makeq() {
qlist q = (qlist)malloc(sizeof(struct qnode));
q->front = NULL;
q->gear = NULL;
return q;
}
int isempty(qlist q) {
return (q->front == NULL);
}
void insertq(qlist q, int x) {
list temp = (list)malloc(sizeof(struct lnode));
temp->data = x;
temp->nextnode = NULL;
if (isempty(q)) q->front = q->gear = temp;
else {
q->gear->nextnode = temp;
q->gear = temp;
}
}
int deleteq(qlist q) {
list frontcell;
int frontnum;
if (isempty(q)) return -1;
else {
frontcell = q->front;
if (q->front == q->gear) {
q->front = NULL;
q->gear = NULL;
}
else {
q->front = q->front->nextnode;
}
frontnum = frontcell->data;
}
free(frontcell);
return frontnum;
}
//6.广度优先遍历
void BFS(Lgraph g, int v0, int visit[]) {
//访问v
qlist q = makeq();
insertq(q, v0);
visitnode(v0);
visit[v0] = true;
pvnode w;
int i;
while (!isempty(q)) {
i = deleteq(q);
for (w = g->Glist[i].firstnode; w; w = w->next) {
//v的所有邻接点进表
if (visit[w->v] == false) {
insertq(q, w->v);
visitnode(w->v);
visit[w->v] = true;
}
}
}
}
int main() {
Lgraph g = buildgraph();
int visit[maxsize];
initiate(visit);
for (int i = 0; i < g->N; i++) {
if (!visit[i]) {
printf("{");
DFS(g, i, visit);
printf("}\n");
}
}
initiate(visit);
for (int i = 0; i < g->N; i++) {
if (!visit[i]) {
printf("{");
BFS(g, i, visit);
printf("}\n");
}
}
system("pause");
return 0;
}