晚上听了一节同学的计算机软件选修课,刚好讲的图的相关算法,今天先实现深度优先搜索吧。
深度优先搜索,用我的理解,是先设置一个起始点,然后搜索其邻接点,用一个visited数组存储该点是否未被访问,若未被访问,则作为新的起始点,搜索其邻接点,这里就涉及到递归算法。
存在几个问题:
- 图的邻接矩阵的定义:就是一个二维数组,数组下标是边的两个端点,若该边存在,则相应数组元素置1。
- 利用图的邻接矩阵寻找当前起始点的邻接点,满足元素值为1且未被访问。
- 找到下一个邻接点后需要将visited相应元素置1!!此处需要实现一个递归,直到所有点都被访问后递归结束。
完整代码如下:
const int MAX_VERTEX_NUM=10;//顶点个数;
typedef int VERTYPE;
//图的定义
typedef struct{
VERTYPE vexs[MAX_VERTEX_NUM];//顶点集合
int visited[MAX_VERTEX_NUM];
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵
int vexnum, arcnum;//顶点个数与弧的个数
}mgraph, *MGraph;
//图的初始化
void Init_MGraph(MGraph &g){
g=(MGraph)malloc(sizeof(mgraph));
g->arcnum=g->vexnum=0;
for(int i=0;i<MAX_VERTEX_NUM;i++)
g->vexs[i]=0;
for(int i=0;i<MAX_VERTEX_NUM;i++)
g->visited[i]=0;
for(int i=0;i<MAX_VERTEX_NUM;i++){
for(int j=0;j<MAX_VERTEX_NUM;j++)
g->arcs[i][j]=0;
}
}
//增加顶点
void add_vexs(MGraph &g){
cout<<"请输入图的顶点个数:"<<endl;
cin>>g->vexnum;
//cout<<g->vexnum<<" 333"<<endl;
cout<<"请输入顶点的值:"<<endl;
for(int i=0;i<g->vexnum;i++){
cin>>g->vexs[i];
}
}
//增加边
void add_arcs(MGraph &g){
cout<<"请输入边的个数:"<<endl;
cin>>g->arcnum;
VERTYPE ch1,ch2;
int row, col;
cout<<"请输入每条边的端点:"<<endl;
for(int i=0;i<g->arcnum;i++){
cin>>ch1;//左端点
cin>>ch2;//右端点
for(int j=0;j<g->vexnum;j++){//该边必须存在于图中
if(g->vexs[j]==ch1) row=j;
if(g->vexs[j]==ch2) col=j;
}
//cout<<row<<" "<<col<<endl;
g->arcs[row][col]=1;
g->arcs[col][row]=1;
}
}
void create_MGraph(MGraph &g){
add_vexs(g);
add_arcs(g);
}
void print_MGraph(MGraph g){
cout<<"输出邻接矩阵:"<<endl;
cout<<" ";
for(int i=0;i<g->vexnum;i++){
cout<<" "<<g->vexs[i];
}
cout<<endl;
for(int i=0;i<g->vexnum;i++){
cout<<g->vexs[i]<<" ";
for(int j=0;j<g->vexnum;j++)
cout<<g->arcs[i][j]<<" ";
cout<<endl;
}
}
void visit(MGraph &g, int i){
cout<<g->vexs[i]<<" ";
g->visited[i]=1;
}
void DFSTraverse(MGraph &g, int i){
visit(g,i);
for(int j=0;j<g->vexnum;j++){
if(g->arcs[i][j]&&!g->visited[j])
DFSTraverse(g,j);
}
return;
}
int main(){
MGraph g;
Init_MGraph(g);
create_MGraph(g);
print_MGraph(g);
cout<<"图的DFS的遍历结果为:"<<endl;
DFSTraverse(g,0);
}
效果如下: