/***
*** 图的存储和遍历
***/
#include <iostream>
#include <stdlib.h>
using namespace std;
#define OK 1
#define OVERFLOW -2
#define ERROR 0
#define MaxInt 32767
#define MVNum 100 // 最大顶点数
#define MAXQSIZE 100 // 队列最大值
typedef struct { // 队列结构体定义
int *base;
int front;
int rear;
}SqQueue;
//初始化队列
int InitSqQueue(SqQueue &S){
S.base = new int[MAXQSIZE];
if(!S.base){
exit(OVERFLOW);
}
S.front = 0;
S.rear = 0;
return OK;
}
//入队
int EnQueue(SqQueue &S , int e){
if((S.rear+1)&&MAXQSIZE == S.front){
return ERROR;
}
S.base[S.rear] = e;
S.rear = (S.rear+1)%MAXQSIZE;
return OK;
}
//出队
int DeQueue(SqQueue &S){
if(S.rear == S.front){
return ERROR;
}
S.front = (S.front+1)%MAXQSIZE;
return OK;
}
//判断队列是否为空
int QueueEmpty(SqQueue S){
if(S.rear == S.front){
return 1;
}else{
return 0;
}
}
typedef int VertexType; // 顶点数据类型为整形
typedef int ArcType; // 边的权值类型为整形
typedef struct {
VertexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的顶点数和边数
} AMGraph;
bool visited[MVNum];//辅助数组
//这个函数如果不是u不是char类型的话其实可以不用写,
//因为在createUDG函数里我输入的是最前面几行已经定义好的int型
int locateVex(AMGraph G,VertexType u){
for(int i=0;i<=G.vexnum;i++){
if(u == G.vexs[i])
return i;
}
return -1;
}
//采用邻接矩阵创建无向图
void CreateUDG(AMGraph &G)
{
cout<<"输入顶点数和边数"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"依次输入顶点的序号(从0开始)"<<endl;
for(int i=0;i<G.vexnum;i++)
cin>>G.vexs[i];
for(int i=0;i<G.vexnum;i++){
for(int j=0;j<G.vexnum;j++){
G.arcs[i][j] = MaxInt;
}
}
for(int i=0;i<G.arcnum;i++){
VertexType v1,v2;
int w;//权值
cout<<"输入两个顶点和两条边之间的权值"<<endl;
cin>>v1>>v2>>w;
int j = locateVex(G,v1);//定位顶点在矩阵中的位置
int k = locateVex(G,v2);//同上
G.arcs[j][k] = w;//因为矩阵对称
G.arcs[k][j] = w;//所以对称
}
}
//第一个邻接点
int firstAdjVex(AMGraph G, int u){
for(int i=0;i<G.vexnum;i++){
if(G.arcs[u][i]!=MaxInt&&visited[i]==false) return i;
}
return -1;
}
//
int nextAdjVex(AMGraph G,int u,int w){
for(int i=w;i<G.vexnum;i++){
if(G.arcs[u][i]!=MaxInt&&visited[i]==false) return i;
}
return -1;
}
//从第v个顶点出发,广度优先搜索遍历图G
void BFS(AMGraph G, int v) {
cout<<G.vexs[v]<<" ";
visited[v]=true;
SqQueue S;//【定义队列】
InitSqQueue(S);//【初始化队列】
EnQueue(S,v);//同样,这里老师要求的是int型,所以这里G.vexs[v]也相当于v,【进队】
while(!(QueueEmpty(S))){
int u = S.base[S.front];//这里必须要写,如果在循环外的话,u会永远不变
DeQueue(S);//【出队】,每次出队头指针都会+1,指向下一个数据
for(int w=firstAdjVex(G,u);w>=0;w=nextAdjVex(G,u,w)){//访问完一次会接着访问未访问的邻接点
if(!visited[w]){//访问完就设置visited[w]为1,即已访问
cout<<G.vexs[w]<<" ";
visited[w]=true;
EnQueue(S,G.vexs[w]);
}
}
}
}
// 从第v个顶点出发,深度优先搜索遍历图G
void DFS(AMGraph G, int v) {
cout<<G.vexs[v]<<" ";
visited[v] = true;
for(int w=firstAdjVex(G,v);w>=0;w=nextAdjVex(G,v,w)){//同上
if(!visited[w]){
DFS(G,w);
}
}
}
//输出邻接矩阵
void printGraph(AMGraph G)
{
int i,j;
cout<<endl<<"图的邻接矩阵:"<<endl;
for (i=0;i<G.vexnum;i++) {
for (j=0; j<G.vexnum; j++)
cout<<' '<<G.arcs[i][j];
cout<<endl;
}
}
int main() {
AMGraph G;
cout<<"-------------*图的遍历*-------------"<<endl;
CreateUDG(G); // 创建无向图
printGraph(G); // 打印邻接矩阵
cout<<endl;
cout<<"深度优先搜索序列: ";
for( int i=0; i<G.vexnum; i++)
visited[i] = 0;
DFS(G, 0);
cout<<endl;
cout<<"广度优先搜索序列: ";
for( int i=0; i<G.vexnum; i++)
visited[i] = 0;
BFS(G, 0);
cout<<endl;
return OK;
}
之前的代码有点毛病,已改正