图的遍历

实验八图的遍历操作

一、   实验目的

1.掌握图的基本存储方法;

2.熟练掌握图的两种搜索路径的遍历方法。

二、   实验内容

1.假设图中存在以下结点:a b c d e f g, 以邻接矩阵存储,请设计程序深度优先遍历该图

 

 

2.假设图中存在以下结点:a b c d e f g, 以邻接表存储,请设计程序广度优先遍历该图

 

a

c

d

b

e

f

g

 

 

 

 

 

 

 

 

//图的遍历是指按某条搜索路径访问图中每个结点,使得每个结点均被访问一次,而且仅被访问一次。图的遍历有深度遍历算法和广度遍历算法,程序如下:

 #include

 #define INFINITY 32767

 #define MAX_VEX 20 //最大顶点个数

 #define QUEUE_SIZE (MAX_VEX+1) //队列长度

 using namespace std;

 bool *visited; //访问标志数组

 //图的邻接矩阵存储结构

 typedef struct{

   char *vexs; //顶点向量

   int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵

   int vexnum,arcnum; //图的当前顶点数和弧数

 }Graph;

 

 

//队列类

 class Queue{

   public:

   void InitQueue(){

     base=(int*)malloc(QUEUE_SIZE*sizeof(int));

     front=rear=0;

   }

   void EnQueue(int e){

     base[rear]=e;

     rear=(rear+1)%QUEUE_SIZE;

   }

   void DeQueue(int &e){

     e=base[front];

     front=(front+1)%QUEUE_SIZE;

   }

   public:

   int *base;

   int front;

   int rear;

 };

 

 

//图G中查找元素c的位置

 int Locate(Graph G,char c){

   for(int i=0;i

   if(G.vexs[i]==c) return i;

   return -1;

 }

 

 

//创建无向网

 void CreateUDN(Graph &G){

   int i,j,s1,s2;

   int w=1;

   char a,b,temp;

   printf("输入顶点数和弧数:");

  scanf("%d%d",&G.vexnum,&G.arcnum);

   temp=getchar(); //接收回车

   G.vexs=(char*)malloc(G.vexnum*sizeof(char)); //分配顶点数目

   printf("输入%d个顶点.\n",G.vexnum);

   for(i=0;i初始化顶点

     printf("输入顶点%d:",i);

     scanf("%c",&G.vexs[i]);

     temp=getchar(); //接收回车

   }

   for(i=0;i初始化邻接矩阵

     for(j=0;j

       G.arcs[i][j]=INFINITY;

   printf("输入%d条弧.\n",G.arcnum);

   for(i=0;i初始化弧

     printf("输入弧%d:",i);

     scanf("%c %c",&a,&b); //输入一条边依附的顶点和权值

     temp=getchar(); //接收回车

     s1=Locate(G,a);

     s2=Locate(G,b);

     G.arcs[s1][s2]=G.arcs[s2][s1]=1;

   }

 }

 

 

//图G中顶点k的第一个邻接顶点

 int FirstVex(Graph G,int k){

   if(k>=0 && k合理

     for(int i=0;i

       if(G.arcs[k][i]!=INFINITY) return i;

   }

   return -1;

 }

 

 

//图G中顶点i的第j个邻接顶点的下一个邻接顶点

 int NextVex(Graph G,int i,int j){

   if(i>=0 && i=0 && j合理

     for(int k=j+1;k

       if(G.arcs[i][k]!=INFINITY) return k;

   }

   return -1;

 }

 

 

//深度优先遍历

 void DFS(Graph G,int k){

   int i;

   if(k==-1){ //第一次执行DFS时,k为-1

     for(i=0;i

       if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS

   }

   else{

     visited[k]=true;

     printf("%c ",G.vexs[k]); //访问第k个顶点

    for(i=FirstVex(G,k);i>=0;i=NextVex(G,k,i))

       if(!visited[i]) DFS(G,i); //对k的尚未访问的邻接顶点i递归调用DFS

   }

 }

 

 

}

 

 

//主函数

 void main(){

   int i;

   Graph G;

   CreateUDN(G);

   visited=(bool*)malloc(G.vexnum*sizeof(bool));

   printf("\n深度优先遍历:");

   for(i=0;i

   visited[i]=false;

   DFS(G,-1);

 

   printf("\n程序结束.\n");

 }

#include 

#include 

#include 

using namespacestd; 

 

//下面是循环队列模版 

template 

classMy_queue; 

 

template 

class Node 

private: 

    T data; 

    Node *next; 

public: 

    Node() 

   

        next=0; 

   

    Node(T d)  

   

        data=d; 

        next=0; 

   

    friend My_queue

}; 

 

template 

classMy_queue 

private: 

    Node *tail; 

public: 

    My_queue() 

   

        tail=new Node(); 

        tail->next=tail; 

    } 

 

    ~My_queue() 

   

        clean(); 

        delete tail; 

  

 

    bool empty() 

   

        return (tail->next==tail); 

   

 

    void push(T d) 

  

        Node *p=newNode(d); 

        p->next=tail->next; 

        tail->next=p; 

        tail=p; 

   

 

    T front() 

   

        if(empty()) 

       

            cout<<"queue isempty!"<

            exit(0); 

       

        Node *p=tail->next; 

        T data=p->next->data; 

        return data; 

   

 

    T back() 

   

        if(empty()) 

       

            cout<<"queue isempty!"<

            exit(0); 

       

        T data=tail->data; 

        return data; 

   

 

    void pop() 

   

        Node *p=tail->next; 

        Node *q=p->next; 

        p->next=q->next; 

        if(q==tail) 

            tail=p; 

        delete q; 

   

 

    void clean() 

  

        Node *p=tail->next; 

        Node *q=p->next; 

        while(q!=p) 

       

           p->next=q->next; 

           delete q; 

            p->next=q; 

       

   

}; 

 

#defineMAX_VERTEX_NUM 20 

boolvisited[20];//用于遍历时辅组使用 

int Vex_Num;//统计输出顶点数目 

 

//表结点 

structArcNode 

    int adjvex; //弧所指向顶点的位置 

    ArcNode *nextarc;// 指向下一条弧 

}; 

 

//头结点 

typedef structVNode 

   string data;//顶点名 

    ArcNode *firstarc;//指向第一条关联顶点的弧 

}AdjList[MAX_VERTEX_NUM]; 

 

structALGraph 

    AdjList vertices;//头结点数组 

    int vexnum;//顶点数 

    int arcnum;//边数 

}; 

 

intLocate_Vex(ALGraph G,string x) //定位顶点位置 

    for(intv=0;G.vertices[v].data!=x;v++); 

   return v; 

 

voidCreateDG_ALG(ALGraph &G) 

   //采用邻接表存储表示,构造有向图G 

    string v1,v2; 

    int i,j,k; 

    cout<<"输入顶点数和边数:"; 

    cin>>G.vexnum>>G.arcnum; 

     

    //构造头结点数组 

    cout<<"输入顶点民称:"; 

    for(i=0;i

   

        cin>>G.vertices[i].data; 

        G.vertices[i].firstarc=NULL; 

   

 

    //输入各弧并构造邻接表 

    for(k=0;k

   

        cout<<"按尾->头的顺序输入边所对应的两个顶点:"; 

        cin>>v1>>v2; 

        i=Locate_Vex(G,v1); 

        j=Locate_Vex(G,v2); 

        while(i<0|| i>G.vexnum-1 ||j<0 || j>G.vexnum-1) 

      

           cout<<"结点位置输入错误,重新输入: "; 

            cin>>v1>>v2; 

           i=Locate_Vex(G,v1); 

           j=Locate_Vex(G,v2);  

       

     

        ArcNode *p=new ArcNode; 

        p->adjvex=j; 

        p->nextarc=G.vertices[i].firstarc; 

        G.vertices[i].firstarc=p; 

  

 

//深度优先遍历 

void DFS(ALGraphG,int v) 

    visited[v]=true; 

  cout<

    Vex_Num+=1; 

    if(Vex_Num==G.vexnum) 

        return; 

    ArcNode *p; 

    int w; 

   for(p=G.vertices[v].firstarc;p;p=p->nextarc) 

  

        w=p->adjvex; 

       if(!visited[w]) 

           DFS(G,w); 

  

 

voidDFS_Traverse(ALGraph G) 

    Vex_Num=0; 

   int i,k; 

    for(i=0;i

       visited[i]=false; 

    for(k=0;k

        if(!visited[k]) 

            DFS(G,k); 

 

//广度优先遍历 

voidBFS_Traverse(ALGraph G) 

    Vex_Num=0; 

   int i,k,w; 

  My_queue q; 

    ArcNode *p; 

   for(i=0;i

       visited[i]=false; 

  for(i=0;i

 

       if(!visited[i]) 

       

            visited[i]=true; 

           cout<

            Vex_Num+=1; 

            if(G.vertices[i].firstarc) 

                q.push(i); 

            while(!q.empty()) 

           

                k=q.front(); 

                q.pop(); 

               for(p=G.vertices[k].firstarc;p;p=p->nextarc) 

              

                    w=p->adjvex; 

                   if(!visited[w]) 

                   

                       visited[w]=true; 

                      cout<

                        Vex_Num+=1; 

                       if(Vex_Num==G.vexnum) 

                          break; 

                       if(G.vertices[w].firstarc) 

                           q.push(w); 

                  

               

           

       

   

 

int main() 

        ALGraph G; 

   CreateDG_ALG(G); 

    cout<<"深度优先遍历图为:"; 

    DFS_Traverse(G); 

    cout<

    cout<<"广度优先遍历图为:"; 

    BFS_Traverse(G); 

    cout<

      return 0;

     

你可能感兴趣的:(数据结构,c++)