第六章学习小结

Posted on 2019-05-19 15:10  321小邓  阅读(172)  评论(1)    收藏  举报

学习心得:每节课学了的知识,课后需要做题巩固一下,不然对一些定义不是很清楚,易混淆,而且对很多知识的理解非常模糊,就像上次小测的那个哈夫曼树的表一样,我当时没复习哈夫曼树的表,所以考试时完全写不出来,但是后来看书发现自己早就知道怎么写,只不过当时老师讲的时候不知道那个就叫哈夫曼树的表。

这一章我想讲一下 7-1列出连通集 这道题(因为实践还没写出来)

这道题我的解题思路为:

1.用邻接矩阵来表示无向非连通图

2.分别写出DFS,BFS的遍历代码

因为顶点的名字本身就是顶点的下标,所以我的结构体定义如下

typedef struct  
{
    int arcs[10][10];
    int vexnum,arcnum;
}AMgraph;
View Code

我没有在结构体定义顶点表

然后就是构造一个图的函数了

void CreateUDN(AMgraph &G)
{//构建一个邻接矩阵来存储边 
       cin>>G.vexnum>>G.arcnum;
       for(int i=0;i<G.vexnum;++i)
       {
           for(int j=0;j<G.vexnum;++j)
           {
               G.arcs[i][j]=0;
           }
       }
       for(int k=0;k<G.arcnum;++k)
       {//两个 顶点之间有边,则·其对应矩阵的下标值改为1,无则为0 
           int v1,v2;
           cin>>v1>>v2;
           G.arcs[v1][v2]=1;
           G.arcs[v2][v1]=    G.arcs[v1][v2];
       }
       
}
View Code

邻接矩阵全部初始化为0了

因为visited函数不是全局定义,所以我在主函数中的BFS和DFS调用中加上了调用visited函数的代码

int main() 
{   
    AMgraph G;
    CreateUDN(G);
    bool visited[10];//访问标志数组,其初始值为false
    for(int v=0;v<G.vexnum;++v) visited[v]=false;
    DFSTraverse(G,visited);
    for(int v=0;v<G.vexnum;++v) visited[v]=false;
    BFSTraverse(G,visited);
    return 0;
}
View Code

我用DFSTraverse函数循环调用DFS算法并依次输出联通集

void BFS (AMgraph G, int v,bool visited[])
{ //按广度优先非递归遍历连通图G 
    int t;
    queue<int> q;
    visited[v]=true;
    q.push(v);
    while(!q.empty())
    {//利用队列对邻接矩阵进行广度优先访问 
     t=q.front();
     cout<<t<<" ";
     q.pop();
     for(int w=0;w<G.vexnum;w++)
     {
         if((G.arcs[t][w]!=0)&&(!visited[w]))
         {//当顶点之间有边,并且未被访问过,再次调用BFS进行访问 
             visited[w]=true;
             q.push(w);
         }
      } 
    }
}//BFS

void BFSTraverse(AMgraph G,bool visited[])
{
    for(int p=0;p<G.vexnum;++p)
    {//循环调用BFS直到每一个联通分量皆被访问完 
        if(!visited[p]) 
        {  
        cout<<"{ "; 
          BFS(G,p,visited);
          cout<<"}"<<endl; 
        }
         
    }
}
View Code

BFS算法中使用了队列来进行广搜,我一开始是想参照书上的来打BFS函数的代码,但是后来问了同学有更加简便的方法后,就采用了她那种方法了,其实两种都是借用了队列,我的这段代码可以直接调用函数库,不用再写函数,比较像之前第五章的listleaves那道中的层次遍历函数的写法

完整代码如下

#include <iostream>
#include <queue>
using namespace std;
typedef struct  
{
    int arcs[10][10];
    int vexnum,arcnum;
}AMgraph;
void  DFS(AMgraph G,int v,bool visited[]);
void DFSTraverse(AMgraph G,bool visited[]);
void BFS (AMgraph G, int v,bool visited[]);
void BFSTraverse(AMgraph G,bool visited[]);
void CreateUDN(AMgraph &G)
{//构建一个邻接矩阵来存储边 
       cin>>G.vexnum>>G.arcnum;
       for(int i=0;i<G.vexnum;++i)
       {
           for(int j=0;j<G.vexnum;++j)
           {
               G.arcs[i][j]=0;
           }
       }
       for(int k=0;k<G.arcnum;++k)
       {//两个 顶点之间有边,则·其对应矩阵的下标值改为1,无则为0 
           int v1,v2;
           cin>>v1>>v2;
           G.arcs[v1][v2]=1;
           G.arcs[v2][v1]=    G.arcs[v1][v2];
       }
       
}
int main() 
{   
    AMgraph G;
    CreateUDN(G);
    bool visited[10];//访问标志数组,其初始值为false
    for(int v=0;v<G.vexnum;++v) visited[v]=false;
    DFSTraverse(G,visited);
    for(int v=0;v<G.vexnum;++v) visited[v]=false;
    BFSTraverse(G,visited);
    return 0;
}
void  DFS(AMgraph G,int v,bool visited[]) 
{//从第v个顶点出发递归深度优先遍历图G 
   cout<<v<<" "; visited[v]=true;
   for(int w=0;w<G.vexnum;w++)
   {
            if((G.arcs[v][w]!=0)&&(!visited[w])) DFS(G,w,visited);//当顶点之间有边,并且未被访问过,再次调用DFS进行访问 
       }    
}
void DFSTraverse(AMgraph G,bool visited[])
{
    for(int p=0;p<G.vexnum;++p)
    {//循环调用DFS直到每一个联通分量皆被访问完 
        if(!visited[p]) 
        {  
        cout<<"{ "; 
          DFS(G,p,visited);
          cout<<"}"<<endl; 
        }
         
    }
}
void BFS (AMgraph G, int v,bool visited[])
{ //按广度优先非递归遍历连通图G 
    int t;
    queue<int> q;
    visited[v]=true;
    q.push(v);
    while(!q.empty())
    {//利用队列对邻接矩阵进行广度优先访问 
     t=q.front();
     cout<<t<<" ";
     q.pop();
     for(int w=0;w<G.vexnum;w++)
     {
         if((G.arcs[t][w]!=0)&&(!visited[w]))
         {//当顶点之间有边,并且未被访问过,再次调用BFS进行访问 
             visited[w]=true;
             q.push(w);
         }
      } 
    }
}//BFS

void BFSTraverse(AMgraph G,bool visited[])
{
    for(int p=0;p<G.vexnum;++p)
    {//循环调用BFS直到每一个联通分量皆被访问完 
        if(!visited[p]) 
        {  
        cout<<"{ "; 
          BFS(G,p,visited);
          cout<<"}"<<endl; 
        }
         
    }
}
View Code