图论中的BFS和DFS

其时两种算法还真的不好懂,BFS强调先选择一条路径走完,然后再回到原来的备选路径走,直至结束;DFS强调把所有邻接点遍历完;前者使用堆栈模拟,后者可以用队列模拟。

BFS:

/* Note:Your choice is C IDE */
#include<stdio.h>
#include<stdlib.h>
#define Max 9
#define queueMAX 10
typedef struct Bintree
{
int data;
struct Bintree *next;
}node,*Graph;
node head[Max];
int visited[Max];//对应head[i]遍历情况
int queue[queueMAX];
int front=-1;
int rear=-1;//不占用内存空间 rear从0到queuemax-1 
/*函数的声明*/
void creat_Graph(int start,int end);
void print_Graph(Graph head);
int enqueue(int data);//数据存入队列
int dequeue();//数据出队列
void BFS(int n);//由形参决定搜索开始的点
/*主函数*/
int main(){
int i;
int n;//搜索的起始点
//用数组表示一个图
int node[20][2]={1,2,2,1,1,3,3,1,2,4,4,2,2,5,5,2,3,6,6,3,3,7,7,3,4,8,8,4,5,8,8,5,6,8,8,6,7,8,8,7};
//初始化结构体
for(i=0;i<Max;i++)
 {
  head[i].data=i;
  head[i].next=NULL;
 }
for(i=0;i<Max;i++)
 visited[i]=0;
 //图用邻接链表表示
for(i=0;i<20;i++)
creat_Graph(node[i][0],node[i][1]);
//打印图的邻接链表结构
printf("=======图的邻接链表结构=======\n");
for(i=0;i<Max;i++)
 {
  printf("vertex[%d]=>",i);
  print_Graph(&head[i]);
 }
//广度优先搜索
printf("=====Broad first search=====\n");
printf("搜索的起始点为:\n");
scanf("%d",&n);
printf("搜索路径:\n");
printf("[Begin]=>");
BFS(n);//n作为搜索的起始点
printf("[End]\n");
system("pause");
return 0;
}
/*函数的定义*/
void creat_Graph(int start,int end)
{
Graph pointer,new;
//对新开辟的存储空间初始化
new=malloc(sizeof(node));
new->data=end;
new->next=NULL;
//选择一个节点作为起始点
pointer=&(head[start]);
while(pointer->next!=NULL)
 pointer=pointer->next;
pointer->next=new;
}
/*对于使用过的节点,按序输出,可得预期结果;对于没有使用过的节点,则为孤立节点,则不输出*/
void print_Graph(Graph pointer)
{
Graph pointer1=pointer->next;
while(pointer1!=NULL)
 {
  printf("[%d]=>",pointer1->data);
  pointer1=pointer1->next;
 }
printf("\n");
}
void BFS(int n)//本质上利用队列对链表结构进行处理 
{
Graph pointer;
enqueue(n);
visited[n]=1;
printf("[%d]=>",n);
while(front!=rear)//队列不为空
 {
  n=dequeue();//某元素出队,意味着它的邻节点都要入队,一个元素出队意味着它的相邻元素全部入队,将入队元素挨个出队 
  pointer=head[n].next;//pointer指向链式结构的第二个部分 
  while(pointer!=NULL)//将出队元素的链式结构遍历完 
   {
   	if(visited[pointer->data]==0)//未遍历 全部入队 
   	 {
   	  enqueue(pointer->data);
   	  visited[pointer->data]=1;
   	  printf("[%d]=>",pointer->data);
   	 }
    pointer=pointer->next;//遍历过指向下一个 
   }
 } 
}
int enqueue(int n)
{
if(rear==queueMAX-1)//入队要防止队列满
 return;
else
{
rear++;
queue[rear]=n;
//printf("入队数据为%d\n",queue[rear]);
return 1;
}
}
int dequeue()
{
if(front==rear)//出队列要防止队列为空
 {
 printf("队列已空!\n");
 return;
}
else
 {
  front++;
 // printf("出队数据为%d\n",queue[front]);
  return queue[front];
 }
}

DFS:

#include "stdio.h"
#include "stdlib.h"
#define max 8
typedef struct graphnode
{
int data;
struct graphnode *next;
}node,*graph;
node head[max+1];//结构体对象
int visited[max+1];//遍历记录
void creat_graph(int start,int end)//构造图其实也是构造邻接链表
{
graph pointer;
graph newnode;
newnode=malloc(sizeof(node));
newnode->data=end;
newnode->next=NULL;
pointer=&(head[start]);
while(pointer->next!=NULL)
 pointer=pointer->next;
pointer->next=newnode;
}
void print_graph(graph pointer)
{
graph pointer1=pointer->next;
while(pointer1!=NULL)
{
printf("[%d]=>",pointer1->data);
pointer1=pointer1->next;
}
}
void DFS(int n)
{
graph pointer;
visited[n]=1;
printf("[%d]=>",n);
pointer=head[n].next;
//使用递归实现编程思路,其余交给计算机吧 
while(pointer!=NULL)
{
 if(visited[pointer->data]==1)//该数据被遍历过,pointer指向下一个 
   pointer=pointer->next;
  else//否则的话把该点作为起始点重新进行搜索 
   DFS(pointer->data);
}
}
void freespace(graph pointer,int n)
{
 graph pointer1;
 pointer=pointer->next;
 while(pointer!=NULL)
 {
  pointer1=pointer;
  pointer=pointer->next;
  free(pointer1);
  pointer1=NULL;              
 }
printf("已经释放掉第%d个结构体空间!\n",n);
}
int main(){
int n;//搜索的起始点 
int i;
int node[20][2]={1,2,2,1,1,3,3,1,2,4,4,2,2,5,5,2,3,6,6,3,3,7,7,3,4,8,8,4,5,8,8,5,6,8,8,6,7,8,8,7};//无向图必须看成一个双向图 


for(i=0;i<=max;i++)
 {
  head[i].data=i;
  head[i].next=NULL;
 }


for(i=0;i<=max;i++)
 visited[i]=0;


for(i=0;i<20;i++)
 creat_graph(node[i][0],node[i][1]);


printf("##图的结构##\n");//邻接链表的结构 ,即以某一个顶点为基点,放射性出去连接的点为与之连接的点 
for(i=1;i<=max;i++)
{
printf("vertex[%d]: ",i);
print_graph(&head[i]);
printf("\n");
}
//深度优先搜索 
printf("请你输入您想输入的起点:\n");
scanf("%d",&n);
printf("Depth First search:\n");
printf("[Begin]=>");
DFS(n);
printf("[END]\n");
//释放内存 
for(i=1;i<=max;i++)
 freespace(&head[i],i);
system("pause");
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值