实验项目: 图的存储结构的建立与遍历(搜索)
图的遍历(搜索)算法是图型结构算法的基础,本实验要求编写程序演示图的存储结构的建立和遍历(搜索)过程。
实验要求:
(1)能够建立(有向和无向)图的邻接矩阵和邻接表存储结构
(2)能够在邻接矩阵和邻接表存储结构上对(有向和无向)图进行深度优先(递归和非递归都要求)和广度优先搜索
(3)能够存储和显示相应的搜索结果(深度优先或广度优先生成森林(或生成树)、深度优先或广度优先序列和编号)
(4)以文件形式输入图的顶点和边,并显示相应的结果。要求顶点不少于10个,边不少于13个
⑤ 软件功能结构安排合理,界面友好,便于使用
实验备注:
一、上传内容: 1. 实验报告 2. 实验程序源代码;打包为 rar 文件,提交到此处。
二、实验报告格式:见附件“ 实验报告格式 .doc ”截止时间: | 2012年12月31日 星期一 23:55 |
#include <iostream>
#include <cstdio>
#define maxlen 100
using namespace std;
bool visited[maxlen];
struct Link
{
int v;//v为节点编号
Link * next;
};
struct node
{
char element;
struct Link* firstedge;
};//头结点
struct Adgraph
{
int n,e;
node Ad[maxlen];
};//邻接表
struct matrix_graph
{
int n,e;
int mat[maxlen][maxlen];
char element[maxlen];
};
void cre1(matrix_graph &G)//无向图邻接矩阵
{
int i,j,x,y;
cin >> G.n >> G.e;
for(i=0; i<G.n; i++) cin >> G.element[i];
for(i=0; i<G.n; i++)
for(j=0; j<G.n; j++)
G.mat[i][j]=0;
for(i=0; i<G.e; i++)
{
cin >> x >> y;
G.mat[x][y]=1;
G.mat[y][x]=1;//无向图
}
for(i=0; i<G.n; i++)
{
for(j=0; j<G.n; j++)
cout << G.mat[i][j] << " ";
cout << endl;
}//输出邻接矩阵
}
void DFS1(matrix_graph *G,int i)//邻接矩阵深度优先(递归)
{
int j;
cout << G->element[i]<< " ";
visited[i]=true;
for(j=0; j<G->n; j++)if(G->mat[i][j]==1&&!visited[j]) DFS1(G,j);
// 只要找到一个未
// 被访问的,那么就”深“入访问与这个未被访问的节点有关系的节点
}
void DFS1_nonrec(matrix_graph *G,int v)//邻接矩阵深度优先(非递归)
{
int STACK[maxlen];
int top=maxlen;
STACK[--top]=v;//第一个压栈
while(top!=maxlen)
{
int w=STACK[top++];
if(!visited[w])
{
cout << G->element[w] << " ";
visited[w]=true;
}//取栈顶判断,未被访问那么访问标记
for(int i=0; i<G->n; i++)if(!visited[i]&&G->mat[w][i])
STACK[--top]=i;
//如果与栈顶元素有关系的节点没有访问的,全部压栈
}
}
void BFS1(matrix_graph *G,int v)//邻接矩阵的广度优先
{
int Queue[maxlen],front=0,rear=0,w;
visited[v]=true;
Queue[rear++]=v;
cout << G->element[v] << " ";
//源元素,访问并标记,入队
while(front!=rear)
{
v=Queue[front++];//出队
for(w=0; w<G->n; w++)
{
if(!visited[w]&&G->mat[v][w])
{
cout <<G->element[w] << " ";
visited[w]=true;
Queue[rear++]=w;
}
// 如果出队之后的元素未被访问,那么访问标记,
// 循环结束之后所有与它有关的元素都访问完(BFS)
}
}
}
void cre2(Adgraph* G)//邻接表建立
{
int k,i,j;
cin >> G->n >> G->e;//节点和边
for (k=0; k<G->n; k++)
{
cin >> G->Ad[k].element;
G->Ad[k].firstedge=NULL;
}//头结点的初始化
for(k=0; k<G->e; k++)
{
cin >> j >> i;
Link* p=new Link;
p->v=i;
p->next=G->Ad[j].firstedge;
G->Ad[j].firstedge=p;//在表头插入
p=new Link;//建立无向图,所以还要反过来链接
p->v=j;
p->next=G->Ad[i].firstedge;
G->Ad[i].firstedge=p;
}
for(i=0; i<G->n; i++)
{
cout << G->Ad[i].element;
Link *m=G->Ad[i].firstedge;
while(m!=NULL)
{
printf("->%c",G->Ad[m->v].element);
m=m->next;
}
printf("->NULL\n");
}//邻接表打印
}
void DFS2(Adgraph* G,int v)//邻接表的递归深先
{
Link *p;
cout << G->Ad[v].element << " ";
visited[v]=true;
p=G->Ad[v].firstedge;
while(p!=NULL)
{
if(!visited[p->v]) DFS2(G,p->v);
p=p->next;
}
}
void DFS2_nonrec(Adgraph* G,int v)//邻接表的非递归深先
{
int STACK[maxlen],top=maxlen;
Link *p=NULL;
STACK[--top]=v;//第一个压栈
while(top!=maxlen)
{
int w=STACK[top++];
if(!visited[w])
{
cout << G->Ad[w].element << " ";
visited[w]=true;
}
for(p=G->Ad[w].firstedge; p!=NULL; p=p->next)
if(!visited[p->v])
STACK[--top]=p->v;//遇到一个没有访问的,压栈,向下搜索
}
}
void BFS2(Adgraph* G,int v)//邻接表的递归广先
{
int Queue[maxlen],front=0,rear=0;
struct Link *p=NULL;
visited[v]=true;
Queue[rear++]=v;
cout << G->Ad[v].element << " ";
while(front!=rear)
{
v=Queue[front++];
p=G->Ad[v].firstedge;
while(p!=NULL&&!visited[p->v])
{
cout <<G->Ad[p->v].element << " ";
visited[p->v]=true;
Queue[rear++]=p->v;
p=p->next;
}
}
}
int main()
{
struct Adgraph G2;
int i,N;
struct matrix_graph G1;
printf("1----邻接矩阵(无向图)\n2----邻接表(无向图)\n");
cin >> N;
switch(N)
{
case 0:
return 0;
case 1:
freopen("lab3.txt", "r", stdin);
cre1(G1);//建立邻接矩阵
printf("DFS:");
for(i=0; i<G1.n; i++) visited[i]=false;
for(i=0; i<G1.n; i++)if(!visited[i]) DFS1(&G1,i);
//如果有非联通图,那么需要另外选取源点开始搜索
printf("\nDFS_NONREC:");
for(i=0; i<G1.n; i++) visited[i]=false;
for(i=0; i<G1.n; i++)if(!visited[i])DFS1_nonrec(&G1,i);
printf("\nBFS:");
for(i=0; i<G1.n; i++) visited[i]=false;
for(i=0; i<G1.n; i++)if(!visited[i])BFS1(&G1,i);
fclose(stdin);
break;
case 2:
freopen("lab3.txt", "r", stdin);
cre2(&G2);
printf("DFS:");
for(i=0; i<G2.n; i++) visited[i]=false;
for(i=0; i<G2.n; i++)if(!visited[i]) DFS2(&G2,i);
printf("\nDFS_NONREC:");
for(i=0; i<G2.n; i++) visited[i]=false;
for(i=0; i<G2.n; i++)if(!visited[i]) DFS2_nonrec(&G2,i);
printf("\nBFS:");
for(i=0; i<G2.n; i++) visited[i]=false;
for(i=0; i<G2.n; i++)if(!visited[i]) BFS2(&G2,i);
fclose(stdin);
break;
default:
break;
}
return 0;
}