走进算法世界的大门,发现算法中的奥秘,让我们一起来探险吧。
图(邻接表)的结构体定义
typedef struct ArcNode{ //边表
int adjvex; //边所指向的结点
int data; //边存放的权值
struct ArcNode * next;
}ArcNode;
typedef struct VNode{
ArcNode * firstarc; //该顶点所指向的第一条边
char data;
}VNode;
typedef struct{
VNode vnodes[maxSize];
int n,e;
}AGraph;
图(邻接表)的构建
void createAGraph(AGraph * G){
int i,j,k,w;
ArcNode * arcNode;
printf("输入顶点数和边数:\n");
scanf("%d,%d",&G->n,&G->e);
printf("请输入顶信息:\n");
for(i=0;i<G->n;i++){
scanf("%c",&G->vnodes[i].data);
G->vnodes[i].firstarc = NULL;
}
for(k=0;k<G->e;k++){//录入边表
printf("输入边(vi,vj)下标,和权值\n");
scanf("%d,%d,%d",&i,&j,&w);
arcNode = (ArcNode *)malloc(sizeof(ArcNode));
arcNode->data = w;
arcNode->adjvex = j;
arcNode->next = G->vnodes[i].firstarc;
G->vnodes[i].firstarc = arcNode;
//无向图,a结点和b结点的关系是相同的
arcNode = (ArcNode *)malloc(sizeof(ArcNode));
arcNode->data = w;
arcNode->adjvex = i;
arcNode->next = G->vnodes[j].firstarc;
G->vnodes[i].firstarc = arcNode;
}
}
图(邻接表)的深度优先遍历
思路跟邻接矩阵一样,只不过这里要访问到列表,实际上没什么不同的
void DFS2(AGraph * G,int i){
ArcNode * arcNode;
//先访问结点并标记
printf("%c",G->vnodes[i].data);
visited[i] = 1;
for(arcNode = G->vnodes->firstarc;arcNode;arcNode=arcNode->next){
if(!visited[arcNode->adjvex]){
DFS2(G,arcNode->adjvex);
}
}
}
void DFSTraverse2(AGraph * G){
int i;
for(i=0;i<G->n;i++){
visited[i] = 0; //标记为未访问
}
for(i=0;i<G->n;i++){ //如果是连通图则无需该层循环
if(!visited[i]){
DFS2(G,i);
}
}
}
图(邻接表)的广度优先遍历算法
思路跟邻接矩阵一样,思路上请参考邻接矩阵篇
void BFSTraverse2(AGraph * G){
int i,j;
int que[maxSize];
int front = 0,rear = 0;
ArcNode * arcNode;
for(i=0;i<G->n;i++){
visited[i] = 0 ;
}
for(i=0;i<G->n;i++){
if(visited[i]){
printf("%c",G->vnodes[i].data); //先遍历结点
visited[i] = 1;
rear = (rear+1)%maxSize;
que[rear] = i;
while(rear != front){
front = (front + 1)%maxSize;
j = que[front];
for(arcNode=G->vnodes[j].firstarc;arcNode;arcNode=arcNode->next){
rear = (rear + 1)%maxSize;
que[rear] = arcNode->adjvex;
printf("%c",G->vnodes[arcNode->adjvex].data);
visited[arcNode->adjvex] = 1;
}
}
}
}
}