C語言實現的圖的深度搜索與廣度搜索程序
/*
上機試驗5-圖的建立和遍歷
1)建立【無向】【非連通】圖的鄰接表存儲結構,要求頂點個數不少於15個。
2)用DFS及BFS對此鄰接表進行遍歷,打印出兩種遍歷的頂點訪問順序。
3)給定圖中任意兩個頂點v1和v2及整數k,判斷是否存在從v1到v2的路徑長度為k的簡單路徑,若有打印出路徑上的頂點序列(要求路徑上不含回路)。
進一步:找出從v1到v2的所有路徑長度為k的【簡單】路徑。(簡單路徑是指:頂點序列中不含【重現】的頂點的路徑。)
*/
#include<memory>
#include<cstdio>
#include<malloc.h>
#define PointNum 15
using namespace std;
struct V{
int vertex;
int distance;
int sign;
struct V* next;
}Vertex[PointNum+1];
int P[PointNum];
int union_find(int x) // 並查集
{
while(P[x]!=x)x=P[x];
return x;
}
void DFS(int vertex_);
void BFS(int vertex_);
int DFS(int V1, int V2, int V3, int kn);
int lujing[PointNum+1],lujing_I;
int main()
{
int times,vertexNumbers,edgeNumbers,i,j,V1,V2,Distance,n=1,v1,v2,kn;
struct V *p,*q,*temp;
printf("請輸入您所要進行的測試次數:");
scanf("%d",×);
while(times--)
{
printf("\n第%d組數據輸入.\n",n++);
printf("請輸入頂點數:");
scanf("%d",&vertexNumbers); //要保證vertexNumbers <= PointNum
for( i = 0 ; i < vertexNumbers ; i ++ )
{
Vertex[i].vertex = i;//////////////////////////
Vertex[i].distance = 0;////////////////////////
Vertex[i].sign = 0;
Vertex[i].next = NULL;
}
printf("請輸入邊數:");
scanf("%d",&edgeNumbers); //要保證vertexNumbers <= PointNum
for( i = 0 ; i < edgeNumbers ; i ++ )
{
printf("請輸入數據:");
scanf("%d%d%d",&V1,&V2,&Distance);
p = &Vertex[V1];q = Vertex[V1].next;
while( q != NULL ){
p = q;
q = q->next;
}//出來的時候q指向Vertex[V1]鄰接表的結尾-NULL,
temp = (struct V *)malloc(sizeof(Vertex[0]));
p->next = temp; temp->next = NULL;//接上temp
temp->vertex = V2; temp->distance = Distance;temp->sign = 0; //給temp賦值
p = &Vertex[V2];q = Vertex[V2].next;
while( q != NULL ){
p = q;
q = q->next;
}
temp = (struct V *)malloc(sizeof(Vertex[0]));///////////temp的問題???????
p->next = temp; temp->next = NULL;//接上temp
temp->vertex = V1;temp->distance = Distance;temp->sign = 0; //給temp賦值
}
for(i = 0 ; i < vertexNumbers ; i ++ )
{
printf("\nDFS遍歷的頂點訪問順序 :");
DFS(i);
for(int j = 0 ; j < vertexNumbers ; j ++ )
{
Vertex[j].sign = 0;
}
}
printf("\n");
for(i = 0 ; i < vertexNumbers ; i ++ )
{
for(int j = 0 ; j < vertexNumbers ; j ++ )
{
Vertex[j].sign = 0;
}
printf("\nBFS遍歷的頂點訪問順序 :");
BFS(i);
}
for(j = 0 ; j < vertexNumbers ; j ++ )
{
Vertex[j].sign = 0;
}
printf("輸入v1、v2及整數kn :\n");
scanf("%d%d%d",&v1,&v2,&kn);
for(j = 0 ; j < vertexNumbers ; j ++ )
{
Vertex[j].sign = 0;
}
lujing_I = 0;
DFS(v1,v2,v1,kn);
}
return 0;
}
void BFS(int vertex_)
{
struct V *p = &Vertex[vertex_];
int others[PointNum];
do{
if(Vertex[p->vertex].sign == 0){
printf("%d->",p->vertex);//輸出訪問節點
Vertex[p->vertex].sign = 1;//代表已經訪問過了//
others[p->vertex] = -1;//代表這一個可以繼續進行BFS
}
else others[p->vertex] = p->vertex;//記錄已有的點
p = p->next;//主要
}while(p != NULL);
p = &Vertex[vertex_];
while( p->next != NULL )//有些沒有連接要考慮~~!!!!!!!
{
p = p->next;
if(others[p->vertex] == -1)BFS(p->vertex);
}
}
void DFS(int vertex_)
{
struct V *q = Vertex[vertex_].next;//開始的:p = &Vertex[i];q = Vertex[i].next;
Vertex[vertex_].sign = 1;//代表已經訪問過了
printf("%d->",vertex_);//
do{
for(;q != NULL && Vertex[q->vertex].sign == 1;q = q->next);//判斷節點是否已經訪問過了//原來是q->next != NULL//很大的錯誤:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q.sign == 1(********************
if(q == NULL )return;//(q->next == NULL && vertex_Sum == vertexNumbers)
else DFS(q->vertex);//從q->vertex繼續深搜索 *********************q->sign居然沒有賦初值!!!! //很大的錯誤:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q->sign == 1(**************
}while( q != NULL );//有些沒有連接要考慮~~!!!!!!!!
}
int DFS(int V1, int V2, int V3, int kn)
{
struct V *q = Vertex[V1].next;//開始的
int sum,i;
Vertex[V1].sign = 1;//代表已經訪問過了
lujing[lujing_I ++ ] = V1;//printf("%d->",V1);//
if(V1 == V2)
{
for(sum=0,i=0; i < lujing_I; i++)
{
if(i >= 1 )//從第二個點開始
{
for(q = &Vertex[lujing[i-1]]; q != NULL; q = q->next)
{
if( q->vertex == lujing[i])sum += q->distance;
}
}
}
if(kn==sum)
{
printf("%d到%d距離為%d的路徑為:",V3,kn,sum);
for(i=0; i < lujing_I; i++)
{
printf("%d->",lujing[i]);
}
printf("%d\n",sum);
}
//return sum;
}
do{
for(;q != NULL && Vertex[q->vertex].sign == 1;q = q->next);//判斷節點是否已經訪問過了//原來是q->next != NULL//很大的錯誤:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q.sign == 1(********************
if(q == NULL )return -1;//(q->next == NULL && vertex_Sum == vertexNumbers)
else {
DFS(q->vertex,V2,V3,kn);//從q->vertex繼續深搜索 *********************q->sign居然沒有賦初值!!!! //很大的錯誤:::::::::::::::Vertex[q->vertex].sign == 1不能用:::q->sign == 1(**************
Vertex[q->vertex].sign = 0;lujing_I -- ;q = q->next;
}
}while( q != NULL );//有些沒有連接要考慮~~!!!!!!!!
return 0;
}
/*
輸入:
10
4
4
0 1 34
0 2 55
1 3 55
2 3 34
0 3 89
5
5
0 1 1
0 3 1
0 4 1
1 2 1
1 3 1
7
10
0 1 12
0 4 34
1 2 43
1 5 543
2 3 54
2 4 54
2 5 54
3 6 64
4 5 64
5 6 654
15
16
0 1 1
1 2 1
1 10 1
2 3 1
3 4 1
4 5 1
5 6 1
6 7 1
6 14 1
7 8 1
8 9 1
9 10 1
10 11 1
11 12 1
12 13 1
13 14 1
5
5
5 4 12
0 1 12
0 2 32
3 0 43
4 0 43
輸出:
DFS遍歷的頂點訪問順序 :0 -> 1 -> 2 -> 3 -> 4 ->
DFS遍歷的頂點訪問順序 :1 -> 0 -> 3 -> 4 -> 2 ->
DFS遍歷的頂點訪問順序 :2 -> 1 -> 0 -> 3 -> 4 ->
DFS遍歷的頂點訪問順序 :3 -> 0 -> 1 -> 2 -> 4 ->
DFS遍歷的頂點訪問順序 :4 -> 0 -> 1 -> 2 -> 3 ->
BFS遍歷的頂點訪問順序 :0 -> 1 -> 3 -> 4 -> 2 ->
BFS遍歷的頂點訪問順序 :1 -> 0 -> 2 -> 3 -> 4 ->
BFS遍歷的頂點訪問順序 :2 -> 1 -> 0 -> 3 -> 4 ->
BFS遍歷的頂點訪問順序 :3 -> 0 -> 1 -> 4 -> 2 ->
BFS遍歷的頂點訪問順序 :4 -> 0 -> 1 -> 3 -> 2 ->
DFS遍歷的頂點訪問順序 :0 -> 1 -> 2 -> 3 -> 6 -> 5 -> 4 ->
DFS遍歷的頂點訪問順序 :1 -> 0 -> 4 -> 2 -> 3 -> 6 -> 5 ->
DFS遍歷的頂點訪問順序 :2 -> 1 -> 0 -> 4 -> 5 -> 6 -> 3 ->
DFS遍歷的頂點訪問順序 :3 -> 2 -> 1 -> 0 -> 4 -> 5 -> 6 ->
DFS遍歷的頂點訪問順序 :4 -> 0 -> 1 -> 2 -> 3 -> 6 -> 5 ->
DFS遍歷的頂點訪問順序 :5 -> 1 -> 0 -> 4 -> 2 -> 3 -> 6 ->
DFS遍歷的頂點訪問順序 :6 -> 3 -> 2 -> 1 -> 0 -> 4 -> 5 ->
BFS遍歷的頂點訪問順序 :0 -> 1 -> 4 -> 2 -> 5 -> 3 -> 6 ->
BFS遍歷的頂點訪問順序 :1 -> 0 -> 2 -> 5 -> 4 -> 3 -> 6 ->
BFS遍歷的頂點訪問順序 :2 -> 1 -> 3 -> 4 -> 5 -> 0 -> 6 ->
BFS遍歷的頂點訪問順序 :3 -> 2 -> 6 -> 1 -> 4 -> 5 -> 0 ->
BFS遍歷的頂點訪問順序 :4 -> 0 -> 2 -> 5 -> 1 -> 3 -> 6 ->
BFS遍歷的頂點訪問順序 :5 -> 1 -> 2 -> 4 -> 6 -> 0 -> 3 ->
BFS遍歷的頂點訪問順序 :6 -> 3 -> 5 -> 2 -> 1 -> 4 -> 0 ->
第3組數據輸入.
請輸入頂點數:
*/
C語言實現的圖的深度搜索與廣度搜索程序