下面有图的深度,广度搜索 使用邻接表结构存取的
#include <stdio.h>
#include<stdlib.h>
#define maxnode 30
//注意c里面没有true和false c++有
#define m 20//队列长度
typedef struct st_arc
{
int adjvex;//存放与之相连的边的id
int weight;//存放权重
struct st_arc *nextarc;//指向下一个边结点
}arcnode,*arclink;
typedef struct
{
int vertex;//顶点数据域 存什么自己看着办
struct st_arc *firstarc;//指向第一个边节点
}vernode,adjlist[maxnode];//用向量定义图的邻接表表示的 头节点数组
typedef struct
{
adjlist glist;//邻接表数组
int totalE;//边的个数
int totaldot;//点的个数
int kind;//图的种类标志
}ALGraph;
int queue[maxnode];
int output(ALGraph *graph)
{
vernode * pgraphlist = graph->glist;//一指向邻接表头结点的 指针
arclink temp ;//指向 点节点的临时指针
for (int i=1;i<=graph->totaldot;i++)
{
printf("the no %d dot :",i);//第i个邻接链表的头 指向的一坨节点
temp = pgraphlist[i].firstarc;//将头赋 给临时指针 以便输出整个邻接链表
while(temp != NULL)
{
printf(" ->%d:权(%d):",temp->adjvex,temp->weight);
temp = temp->nextarc;//在邻接表中移动临时指针 使之指向下一个 节点
}
printf("->NULL");
printf("\n");
}
return 0;
}
void dfs(adjlist g,int k,int visited[])
{
arclink p;
int w;
visited[k]=1;//设置已访问标志
printf("%d ",g[k].vertex);//输出 邻接表头节点信息,从第几个邻接表头结点开始搜索
p=g[k].firstarc;//设置寻找序号为 k的第一个未访问过的邻结点的扫描指针
while(p!=null)
{
w=p->adjvex;//取出邻结点序号 即 弧头的指向
if (visited[w]==0)//若未访问过则递归调用, 继续以这为弧尾递归访问,访问过了,则检测下一边接点
dfs(g,w,visited);
p=p->nextarc;//p顺着边表next指针取出下一个边结点
}
}
void trave_dfs(adjlist g,int n)//n为点的数量
{
int i,visited[maxnode];
for(i=1;i<=n;i++)
visited[i]=0;//初始化全没访问过,我们标记其为false 就0吧 C里面没false
for(i=1;i<=n;i++) //每个点都检测
if (visited[i]==0)//当这点未被访问过 则深度搜索
dfs(g,i,visited);//深度随着邻接链表 搜
}
void bfs(adjlist g,int k,int visited[])
{
int front=0,rear=1,w;//队头,队尾
arclink temp;//临时指针
visited[k] = 1;//设置已访问标志
printf("%d\t",k);
queue[rear] = k;//将顶点序号k入队
while(front != rear)//当队列非空时循环这里还可递归实现
{
front = (front+1)%m;//m代表队列的长度 ,这里是循环队列
w = queue[front];//取出队列中顶点序号w
temp = g[w].firstarc;//指向表头节点
while(temp != null)
{
if (visited[temp->adjvex] == 0)
{
visited[temp->adjvex] = 1;//设置已访问标志
printf("%d\t",temp->adjvex);
rear = (rear+1)%m;//队列指针后移
queue[rear]=temp->adjvex;//将顶点j入队
}
temp = temp->nextarc;//顺边表指向下一个结点地址
}
}
}
void trave_bfs(adjlist g,int n)
{
int i,visited[maxnode];//与上面dfs的一样
for(i=1;i<=n;i++)
visited[i]=0;
for(i=1;i<=n;i++)
if (visited[i]==0)
bfs(g,i,visited);
}
int main()
{
freopen("in.txt","r",stdin);
ALGraph g;
printf("please input the total dot of graph\n ");
scanf("%d",&g.totaldot);
//构造n个顶点0个边的图
for(int i=1;i<=g.totaldot;i++)
{
//邻接表的头结点 信息存神马???
scanf("%d",&g.glist[i].vertex);
g.glist[i].firstarc = NULL;
}
//构造邻接表,, 开始输入无向图的弧头 弧尾 权
printf("input the total bian of graph");
scanf("%d",&g.totalE);
int arctail,archead,weight;
arcnode *p,*q;
for (i=1;i<=g.totalE;i++)
{
printf("number %d \n",i);
printf("input the arctail archead and the weight\n");
scanf("%d %d %d",&arctail,&archead,&weight);
p =(arcnode *)malloc(sizeof(arcnode));
p->adjvex = archead;//与之相关连的arc头
p->weight = weight;
//这里是个倒链表 最后输入的最接近g[i].firstarc 每次先将新加 \
入的节点指向前面的已经存在的节点,然后邻接表的头结点指向新加入的节点 \
就像头结点一步一步的向右移动
p->nextarc = g.glist[arctail].firstarc ;
g.glist[arctail].firstarc = p;//这里注意里面是arctail 比如你输入1 2 5 则这里应该在邻接表头节点1的位置加入弧节点的信息
//由于这是无向图 所以要将这个弧头 放到弧尾作头结点的表中
q =(arcnode *)malloc(sizeof(arcnode));
q->adjvex = arctail;//与之相关连的arc尾
q->weight = weight;//权值
//这里是个倒链表 最后输入的最接近g[i].firstarc 每次先将新加 \
入的节点指向前面的已经存在的节点,然后邻接表的头结点指向新加入的节点 \
就像头结点一步一步的向右移动
q->nextarc = g.glist[archead].firstarc ;//这里注意里面是archead 比如你输入1 2 5 则这里应该在邻接表头节点2的位置加入弧节点的信息
g.glist[archead].firstarc = q;
}
//到这里为止无向图的邻接链表已经建好,要是有向图的话,上面选一个写就ok了
output(&g);
//深度搜索
printf("dfs:\n");
trave_dfs(g.glist,g.totaldot);//调用深度优先搜索
printf("\n");
//广度搜索
printf("bfs:\n");
trave_bfs(g.glist,g.totaldot);//调用广度优先搜索
printf("\n");
return 0;
}
/*这里附上in.txt的数据
5
1
2
3
4
5
6
1 2 3
1 3 6
1 4 2
1 5 4
2 4 7
3 5 5*/