数据结构C++版 王红梅 OJ习题

1024: 图的邻接矩阵

Description

利用邻接矩阵存储结构,完成深度优先遍历和广度优先遍历算法。已知部分代码如下(勿改动),只需完成深度遍历DFSTraverse和广度遍历BFSTraverse即可。

#include <iostream>
#include <string>                  
using namespace std;

//循环队列类
const int QueueSize=100;  //循环队列的最大长度
template <class T>        //定义模板类CirQueue
class CirQueue
{
public:
    CirQueue( );                 //构造函数,置空队
    ~ CirQueue( );               //析构函数
    void EnQueue(T x);           //将元素x入队
    T DeQueue( );                //将队头元素出队
    T GetQueue( );               //取队头元素(并不删除)
    bool Empty( );               //判断队列是否为空
 bool Full();
private:
    T data[QueueSize];  //存放队列元素的数组
    int front, rear;    //队头和队尾指针,分别指向队头元素的前一个位置和队尾元素的位置
};

//功    能:初始化空队列
 template <class T>
CirQueue<T>::CirQueue( )
{
 front=rear=0;
}

// 功    能:销毁队列
template <class T>
CirQueue<T>::~CirQueue( )
{
}

//功    能:元素x入队
template <class T>
void CirQueue<T>::EnQueue(T x)
{
    if (Full()) throw "Overflow";
    rear=(rear+1) % QueueSize;   //队尾指针在循环意义下加1
    data[rear]=x;                //在队尾处插入元素
}

//功    能:队头元素出队,返回值为出队元素
template <class T>
T CirQueue<T>::DeQueue( )
{
    if (Empty()) throw "Downflow";
    front=(front+1) % QueueSize;    //队头指针在循环意义下加1
    return data[front];             //读取并返回出队前的队头元素,注意队头指针
}
                                   //指向队头元素的前一个位置
// 功    能:获取队头元素
template <class T>
T CirQueue<T>::GetQueue( )
{  
    int i;
    if (Empty()) throw "Downflow";
    i=(front+1) % QueueSize;  //注意不要给队头指针赋值
    return data[i];
}

// 功    能:判断队列是否为空,若空返回true,否则返回false
template <class T>
bool CirQueue<T>::Empty( )
{
    return front==rear;
}
//功   能:判断队列是否满,若满返回true,否则false
template <class T>
bool CirQueue<T>::Full()
{
 return (rear+1)%QueueSize==front;
}

//Class MGraph
const int MaxSize=20;                     //图中最多顶点个数

int visited[MaxSize];                    //访问标志数组(0表示未访问,1表示已访问)

template <class T>
class MGraph
{
public:
    MGraph(T a[],int n,int e);   //构造函数,初始化具有n个顶点,e条边的图
    void DispMGraph();           //输出图中顶点值和矩阵值              
   
 void DFSTraverse(int v);         //    从v顶点出发深度优先遍历图(一个连通子图)

 void BFSTraverse(int v);         //     从v顶点出发广度优先遍历图(一个连通子图)

private:
    T  vertex[MaxSize];             //存放图中顶点信息的数组
    int arc[MaxSize][MaxSize];      //存放图中顶点关系(边)的数组
    int vertexNum,arcNum;           //图的顶点数和边数
 };

//构造一个邻接矩阵存储的无向图
template <class T>
MGraph<T>::MGraph(T a[], int n, int e)
{
 vertexNum=n;                 //顶点数
 arcNum=e;                    //边数
 int i,j,k;
 for (i=0; i<vertexNum; i++)
  vertex[i]=a[i];          //顶点值
 for (i=0; i<vertexNum; i++)    //初始化邻接矩阵值为0(顶点间无边)
  for (j=0; j<vertexNum; j++)
   arc[i][j]=0;            
 for (k=0; k<arcNum; k++)   //依次输入e条边
 {
  cin>>i>>j;             //输入各条边依附的两个顶点的序号
  arc[i][j]=1;           //置有边标志
  arc[j][i]=1;   
 }
}

//输出图中所有顶点信息,和边信息
template <class T>
void MGraph<T>::DispMGraph( )            
{                                
 int i,j;
    cout<<"  ";
    for(i=0;i<vertexNum;i++)            
  cout<<vertex[i]<<" ";//输出图中所有的顶点
    cout<<endl;
 for(i=0;i<vertexNum;i++)
 {
  cout<<vertex[i]<<" ";
  for(j=0;j<vertexNum;j++)
   cout<<arc[i][j]<<" ";  //输出边值(0/1)
  cout<<endl;
 }
}
//在此处实现深度优先遍历算法


//在此处实现广度优先遍历算法

int main()
{
 string a[]={"A","B","C","D","E","F","G","H","I","J","K","L","M","N"}; //顶点信息
 int i,n,e;
 cin>>n>>e;  //输入顶点个数和边个数
    MGraph<string> G(a,n,e);
 G.DispMGraph();
 for(i=0;i<n;i++)
  visited[i]=0;
 cout<<"DFS:";
 G.DFSTraverse(0);
 cout<<endl;
    for(i=0;i<n;i++)
  visited[i]=0;
 cout<<"BFS:";
 G.BFSTraverse(0);
 return 0;
}


 

Input

第一行为顶点个数和边的条数:6 7
第二行为各条边所对应的顶点序号:0 1 0 3 1 2 1 5 2 4 3 5 4 5

Output

Sample Input

6 7
0 1 0 3 1 2 1 5 2 4 3 5 4 5

Sample Output

  A B C D E F 
A 0 1 0 1 0 0 
B 1 0 1 0 0 1 
C 0 1 0 0 1 0 
D 1 0 0 0 0 1 
E 0 0 1 0 0 1 
F 0 1 0 1 1 0 
DFS:A B C E F D 
BFS:A B D C F E 
//
// Created by Legends丶Hu on 2020/2/5.
//
#include <iostream>

using namespace std;

const int QueueSize = 100;

template<class T>        //定义模板类Queue
class Queue {
public:
    Queue();                 //构造函数,置空队
    ~ Queue();               //析构函数
    void EnQueue(T x);           //将元素x入队
    T DeQueue();                //将队头元素出队
    T GetQueue();               //取队头元素(并不删除)
    bool Empty();               //判断队列是否为空,空返回true,否则返回false
    bool Full();                 //判断队列是否为满,满返回true,否则返回false
private:
    T data[QueueSize];           //存放队列元素的数组
    int front, rear;    //队头和队尾指针,分别指向队头元素所在数组的前一下标和队尾元素的数组下标
};

template<class T>
Queue<T>::Queue() {
    front = rear = QueueSize - 1;
}

template<class T>
Queue<T>::~Queue() {
}

template<class T>
bool Queue<T>::Empty() {
    return front == rear;
}

template<class T>
bool Queue<T>::Full() {
    return (rear + 1) % QueueSize == front;
}

template<class T>
void Queue<T>::EnQueue(T x) {
    if(Full()) throw "Overflow";
    rear = (rear + 1) % QueueSize;
    data[rear] = x;
}

template<class T>
T Queue<T>::DeQueue() {
    if(Empty()) throw "Downflow";
    front = (front + 1) % QueueSize;
    return data[front];
}

template<class T>
T Queue<T>::GetQueue() {
    if(Empty()) throw "Downflow";
    return data[front];
}

const int MaxSize = 20;            //图中最多顶点个数
int visited[MaxSize];              //访问标志数组(0表示未访问,1表示已访问)
template<class T>
class MGraph {
public:
    MGraph(T a[], int n, int e);   //构造函数,初始化具有n个顶点,e条边的图
    void DispMGraph();             //输出图中顶点值和矩阵值

    void DFSTraverse(int v);       //从v顶点出发深度优先遍历图(一个连通子图)
    void BFSTraverse(int v);       //从v顶点出发广度优先遍历图(一个连通子图)
private:
    T vertex[MaxSize];             //存放图中顶点信息的数组
    int arc[MaxSize][MaxSize];     //存放图中顶点关系(边)的数组
    int vertexNum, arcNum;         //图的顶点数和边数
};

//构造一个邻接矩阵存储的无向图
template<class T>
MGraph<T>::MGraph(T a[], int n, int e) {
    vertexNum = n;                 //顶点数
    arcNum = e;                    //边数
    int i, j, k;
    for (i = 0; i < vertexNum; i++)
        vertex[i] = a[i];          //顶点值
    for (i = 0; i < vertexNum; i++)    //初始化邻接矩阵值为0(顶点间无边)
        for (j = 0; j < vertexNum; j++)
            arc[i][j] = 0;
    for (k = 0; k < arcNum; k++)   //依次输入e条边
    {
        cin >> i >> j;             //输入各条边依附的两个顶点的序号
        arc[i][j] = 1;           //置有边标志
        arc[j][i] = 1;
    }
}

//输出图中所有顶点信息,和边信息
template<class T>
void MGraph<T>::DispMGraph() {
    int i, j;
    cout << "  ";
    for (i = 0; i < vertexNum; i++)
        cout << vertex[i] << " ";//输出图中所有的顶点
    cout << endl;
    for (i = 0; i < vertexNum; i++) {
        cout << vertex[i] << " ";
        for (j = 0; j < vertexNum; j++)
            cout << arc[i][j] << " ";  //输出边值(0/1)
        cout << endl;
    }
}

template<class T>
void MGraph<T>::DFSTraverse(int v) {
    cout << vertex[v] << " ";
    visited[v] = 1;
    for (int i = 0; i < vertexNum; i++) {
        if (arc[v][i] == 1 && visited[i] == 0)DFSTraverse(i);
    }
}

template<class T>
void MGraph<T>::BFSTraverse(int v) {
    Queue<int> queue;
    queue.EnQueue(v);
    visited[v] = 1;
    cout << vertex[v] << " ";
    while (!queue.Empty()) {
        v = queue.DeQueue();
        for (int i = 0; i < vertexNum; i++) {
            if (arc[i][v] == 1 && visited[i] == 0) {
                cout << vertex[i] << " ";
                queue.EnQueue(i);
                visited[i] = 1;
            }
        }
    }
}
/*
 *
6 7
0 1 0 3 1 2 1 5 2 4 3 5 4 5
 */
int main() {
    string a[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"}; //顶点信息
    int i, n, e;
    cin >> n >> e;  //输入顶点个数和边个数
    MGraph<string> G(a, n, e);
    G.DispMGraph();
    for (i = 0; i < n; i++)
        visited[i] = 0;
    cout << "DFS:";
    G.DFSTraverse(0);
    cout << endl;
    for (i = 0; i < n; i++)
        visited[i] = 0;
    cout << "BFS:";
    G.BFSTraverse(0);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值