图的遍历【做题记录】c++

用邻接矩阵实现无向图(深度遍历、广度遍历)

【输入输出】 第一行输入顶点的个数n,第二行输入n个顶点的值。第三行输入边的个数m,下面m行输入边的起点和终点坐标。最后一行输入遍历的起始点的值。从指定的顶点出发无法访问到的顶点不用遍历。

【测试数据】

8

A B C D E F G H

9

0 1

0 2

1 3

1 4

2 5

2 6

3 7

4 7

5 6

A

输出

【代码】

/**使用邻接矩阵存储图
无向图
*/
#include<iostream>
#include<limits.h>
#define MAX_V_NUM 20  //顶点的最大个数
using namespace std;

/**图类*/
template <class T>
class MGraph
{
private:
    T vertex[MAX_V_NUM];//图元素的一维数组
    int arc[MAX_V_NUM][MAX_V_NUM];//图的邻接矩阵,二维数组
    int vexNum, arcNum;//元素个数,边的个数
public:
    MGraph()//构造函数,根据类型创建邻接矩阵
    {
        cin >> vexNum;
        for (int i = 0; i < vexNum; i++)
        {
            cin >> vertex[i];  //输入图元素的一维数组
        }
        for (int i = 0; i < vexNum; i++)
        {
            for (int j = 0; j < vexNum; j++)
                arc[i][j] = 0;
        }
        cin >> arcNum;
        for (int i = 0; i < arcNum; i++)
        {
            int start, end;
            cin >> start >> end;
            arc[start][end] = 1;
            arc[end][start] = 1;
        }
    }
    ~MGraph( ) {};
    void DFSTraverse(int v);//深度遍历
    void BFSTraverse(int v);//广度遍历
    int getIndex(T vertex1);//获得指定顶点的下标
}; 

//深度遍历,递归
template <class T>
void MGraph<T>::DFSTraverse(int v)
{
    static int visited[MAX_V_NUM]={0}; //定义为静态数组
    cout<<vertex[v]<<" ";
    visited[v]=1;
    for(int j=0;j<vexNum;j++)
    {
        if(arc[v][j]==1&&visited[j]==0) //有边并且没被访问过
        {
            DFSTraverse(j);
        }
    }
}

//广度遍历,队列
template <class T>
void MGraph<T>::BFSTraverse(int v)
{
    bool visited[MAX_V_NUM] = {false}; // 标记顶点是否被访问过
    int queue[MAX_V_NUM]; // 用于存储待访问的顶点
    int front = 0, rear = 0;

    visited[v] = true;
    cout << vertex[v] << " ";
    queue[rear++] = v;

    while (front != rear)
    {
        int cur = queue[front++];
        for (int i = 0; i < vexNum; i++)
        {
            if (arc[cur][i] == 1 && !visited[i])
            {
                visited[i] = true;
                cout << vertex[i] << " ";
                queue[rear++] = i;
            }
        }
    }
}

template <class T>
/**获取对应值的下标*/
int MGraph<T>::getIndex(T vertex1)
{
    int i;
    for(i=0;i<vexNum;i++)
    {
        if(vertex[i]==vertex1)
        {
            return i;
        }
    }
    return -1;//找不到对应的顶点
}


int main()
{

    MGraph<char> graph;
    //graph.printMG();
    //graph.printMatrix();
    char v;
    //cout<<"\n请输入遍历的起始顶点";
    cin>>v;

    cout<<"-----------------\n深度优先遍历的结果:";
    graph.DFSTraverse(graph.getIndex(v));
    cout<<"\n-----------------\n广度优先遍历的结果:";
    graph.BFSTraverse(graph.getIndex(v));
    //cout<<"\n-----------------\n"<<v<<"的度:"<<graph.getDegree(v);

    return 0;
}

用邻接表实现有向网(深度遍历、广度遍历)

【输入输出】 第一行输入顶点的个数n,第二行输入n个顶点的值,为字符型。第三行输入边的个数m,下面m行输入边的起点下标、终点下标和权值(int型)。最后一行输入遍历的起始点,用点的值表示。从指定的起始点出发无法访问到的顶点不用进行遍历。

采用头插法插入链表。

【测试数据】

8

A B C D E F G H

8

0 1 1

0 2 2

1 3 3

4 1 4

3 5 5

5 4 6

2 6 7

2 7 8

A

输出

【代码】

/**邻接表表示有向网*/
#include<iostream>
#include<queue>
#define  MAX_V_NUM 20//最大顶点个数
using namespace std;
/**边表的结构体*/
struct ArcNode
{
    int adjvex;//邻接点在数组中的位置下标
    struct ArcNode* nextArc;//指向下一个邻接点的指针
    int weight;//权值,网才有权值
};
/**顶点的结构体*/
template <class T>
struct VNode
{
    T vertex;//顶点的数据域
    ArcNode* firstArc;//指向邻接点的指针
};
/**邻接表类*/
template <class T>
class ALGraph
{
private:
    VNode<T> AdjList[MAX_V_NUM];//顶点表的数组
    int vexNum, arcNum;//记录图中顶点数和边或弧数
    bool visited[MAX_V_NUM] = { false }; // 定义visited数组
public:
    ALGraph();//构造函数
    ~ALGraph() {}; //析构函数
    int getIndex(T vertex);//获得顶点的下标
    void DFSTraverse(int v);
    void BFSTraverse(int v);
    void createDN();//构造有向网
    void setVertex(int index, T value);
    void incrementVexNum();
};

template <class T>
ALGraph<T>::ALGraph() {
    // 将顶点数和边数初始化为0
    vexNum = 0;
    arcNum = 0;
    // 顶点表的数组初始化
    for (int i = 0; i < MAX_V_NUM; i++) {
        AdjList[i].firstArc = NULL;
    }
}

// 构建有向图
template <class T>
void ALGraph<T>::createDN() {
    int u, v, w;
    // 输入起点下标,终点下标,权值
    cin >> u >> v >> w;
    ArcNode* p = new ArcNode; //定义邻接表的p指针
    p->adjvex = v; //传入邻接点在数组中的终点位置下标
    p->weight = w; //传入对应的权值
    // 头插法插入新的数据
    p->nextArc = AdjList[u].firstArc;
    AdjList[u].firstArc = p;
    arcNum++; //边数增加
}

template <class T>
void ALGraph<T>::DFSTraverse(int v) {
    visited[v] = true;
    cout << AdjList[v].vertex << " ";
    for (ArcNode* p = AdjList[v].firstArc; p != NULL; p = p->nextArc) {
        int w = p->adjvex;
        if (!visited[w]) {
            DFSTraverse(w);
        }
    }
}

//广度遍历
template <class T>
void ALGraph<T>::BFSTraverse(int v) {
    queue<int> q;
    //visited数组进行初始化
    for (int i = 0; i < vexNum; i++)
    {
        visited[i] = false;
    }
    visited[v] = true;
    q.push(v);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        cout << AdjList[u].vertex << " ";
        ArcNode* p = AdjList[u].firstArc;
        while (p!=NULL)
        {
            if (!visited[p->adjvex])//判断顶点是否被访问过,没有的话就进入队列,把它的visited值设置为已访问
            {
                q.push(p->adjvex);
                visited[p->adjvex] = true;
            }
            p = p->nextArc;//指向下一个结点
        }
        
    }
}

//获取顶点的下标
template <class T>
int ALGraph<T>::getIndex(T vertex) { //传入顶点
    for (int i = 0; i < vexNum; i++) { //遍历顶点表
        if (AdjList[i].vertex == vertex) { //如果顶点表的数据域与传入要查找的顶点相同的话,就返回此时的下标
            return i;
        }
    }
    return -1; //如果没找到,就返回-1
}
//更改顶点表的数据域,传入下标和数据
template <class T>
void ALGraph<T>::setVertex(int index, T value) {
    if (index >= 0 && index < MAX_V_NUM) {
        AdjList[index].vertex = value;
    }
}
//vexNum为私有属性,不能直接访问
template <class T>
void ALGraph<T>::incrementVexNum() {
    if (vexNum < MAX_V_NUM) {
        vexNum++;
    }
}

int main()
{
    ALGraph<char> graph;
    int n, m;
    // 输入顶点的个数
    cin >> n;
    // 输入顶点
    for (int i = 0; i < n; i++) {
        char v;
        cin >> v;
        graph.setVertex(i, v);
        graph.incrementVexNum();
    }
    // 输入边的个数
    cin >> m;
    // 输入边的起点下标,终点下标和权值。
    for (int i = 0; i < m; i++) {
        graph.createDN();
    }
    //graph.printALG();
    char v;
    //cout<<"\n请输入遍历的起始顶点";
    cin >> v;

    cout << "-----------------\n深度优先遍历的结果:";
    graph.DFSTraverse(graph.getIndex(v));
    cout << "\n-----------------\n广度优先遍历的结果:";
    graph.BFSTraverse(graph.getIndex(v));
    return 0;
}

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值