C++笔记-二维棋盘数组使用BFS(宽度优先遍历)

Posted IT1995

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++笔记-二维棋盘数组使用BFS(宽度优先遍历)相关的知识,希望对你有一定的参考价值。

这里只对一个顶点只能上下左右,不能和左上,左下,右上,右下连起来。

思路步骤:

1.二维棋盘数据转链接表;

2.邻接表直接进行BFS

源码如下:

#include <QDebug>
#include <QVector>
#include <QQueue>

#define MAX_COLUMN 6 + 2
#define MAX_ROW 6 + 2

//用-1包住,保证处理的统一
int map1[MAX_ROW][MAX_COLUMN] = {
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, 1, -1,
    -1, -1, -1, -1, -1, -1, 0, -1,
    -1, -1, -1, -1, -1, -1, 0, -1,
    -1, -1, -1, -1, -1, -1, 0, -1,
    -1, -1, -1, -1, 1, 1, 0, -1,
    -1, -1, -1, -1, -1, -1, -1, -1
};

struct Point{

    Point(int vNum, int x, int y) {

        this->vNum = vNum;
        this->x = x;
        this->y = y;
    }

    int vNum = -1;		//顶点号
    int x;			//x轴
    int y;			//y轴

    friend QDebug operator << (QDebug os, Point &test){

        os << "(顶点:" << test.vNum << ", x:" << test.x << ", y:" << test.y << ")";
        return os;
    }
};

class Graph {

public:
    Graph(int map[MAX_ROW][MAX_COLUMN]) {

        memcpy(m_map, map, sizeof(m_map));

        //不为-1的都是顶点
        int vCount = 0;

        for (int i = 0; i < MAX_ROW; i++) {

            for (int j = 0; j < MAX_COLUMN; j++) {

                if (map[i][j] != -1) {

                    Point point(vCount++, i, j);
                    QVector<Point> ve;
                    ve.append(point);
                    m_adj.append(ve);
                }
            }
        }

        if (vCount == 0) {

            qDebug() << "退出" << endl;
            exit(-1);
        }

        this->m_v = vCount;

        analysisEdge();
    }

    //打印邻接表
    void print() {

        for (int i = 0; i < this->m_v; ++i) {

            qDebug() << "顶点:" << this->m_adj[i][0].vNum << " x:" << this->m_adj[i][0].x << " y:" << this->m_adj[i][0].y << " 的邻接表!";
            for (int j = 0; j < this->m_adj[i].size(); j++) {

                qDebug() << "顶点:" << this->m_adj[i][j].vNum << " x:" << this->m_adj[i][j].x << " y:" << this->m_adj[i][j].y;
            }

            qDebug() << "------------------------------------";
        }
    }

    void bfs(int startV){

        bool visited[this->m_v];

        for(int i = 0; i < this->m_v; i++){

            visited[i] = false;
        }

        Point point = getPointByVertex(startV);
        if(point.vNum == -1){

            qDebug() << "顶点错误!";
            exit(0);
        }

        QQueue<Point> queue;
        queue.push_back(point);
        visited[startV] = true;

        while(!queue.empty()){

            Point s = queue.front();
            queue.pop_front();

            // start todo something
            qDebug() << s;

            // end todo something

            for(int i = 0; i < this->m_adj[s.vNum].size(); i++){

                int curretV = this->m_adj[s.vNum][i].vNum;
                if(visited[curretV] == false){

                    visited[curretV] = true;
                    queue.push_back(this->m_adj[s.vNum][i]);
                }
            }
        }
    }

protected:

    //通过坐标获取顶点号
    Point getPointByPosXAndPosY(int x, int y) {

        for (int i = 0; i < this->m_v; i++) {

            if (this->m_adj[i][0].x == x && this->m_adj[i][0].y == y) {

                return this->m_adj[i][0];
            }
        }

        return Point(-1, -1, -1);
    }

    //通过顶点号返回Point
    Point getPointByVertex(int v){

        for(int i = 0; i < this->m_v; i++){

            if(this->m_adj[i][0].vNum == v){

                return this->m_adj[i][0];
            }
        }

        return Point(-1, -1, -1);
    }

    void analysisEdge() {

        //分析下边,这个顶点,如果周围一圈都是非-1的数,说明都可达。
        for (int i = 0; i < this->m_v; i++) {


            //左上
//            if (m_map[this->m_adj[i][0].x - 1][this->m_adj[i][0].y - 1] != -1) {

//                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x - 1, this->m_adj[i][0].y - 1);
//                if (point.vNum != -1) {

//                    //顶点是从1开始算,但下标是从0开始
//                    m_adj[this->m_adj[i][0].vNum].push_back(point);
//                }
//            }

            //正上
            if (m_map[this->m_adj[i][0].x - 1][this->m_adj[i][0].y] != -1) {

                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x - 1, this->m_adj[i][0].y);
                if (point.vNum != -1) {

                    //顶点是从1开始算,但下标是从0开始
                    m_adj[this->m_adj[i][0].vNum].push_back(point);
                }
            }

            //右上
//            if (m_map[this->m_adj[i][0].x - 1][this->m_adj[i][0].y + 1] != -1) {

//                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x - 1, this->m_adj[i][0].y + 1);
//                if (point.vNum != -1) {

//                    //顶点是从1开始算,但下标是从0开始
//                    m_adj[this->m_adj[i][0].vNum].push_back(point);
//                }
//            }

            //正右
            if (m_map[this->m_adj[i][0].x][this->m_adj[i][0].y + 1] != -1) {

                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x, this->m_adj[i][0].y + 1);
                if (point.vNum != -1) {

                    //顶点是从1开始算,但下标是从0开始
                    m_adj[this->m_adj[i][0].vNum].push_back(point);
                }
            }

            //右下
//            if (m_map[this->m_adj[i][0].x + 1][this->m_adj[i][0].y + 1] != -1) {

//                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x + 1, this->m_adj[i][0].y + 1);
//                if (point.vNum != -1) {

//                    //顶点是从1开始算,但下标是从0开始
//                    m_adj[this->m_adj[i][0].vNum].push_back(point);
//                }
//            }

            //正下
            if (m_map[this->m_adj[i][0].x + 1][this->m_adj[i][0].y] != -1) {

                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x + 1, this->m_adj[i][0].y);
                if (point.vNum != -1) {

                    //顶点是从1开始算,但下标是从0开始
                    m_adj[this->m_adj[i][0].vNum].push_back(point);
                }
            }

            //左下
//            if (m_map[this->m_adj[i][0].x + 1][this->m_adj[i][0].y - 1] != -1) {

//                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x + 1, this->m_adj[i][0].y - 1);
//                if (point.vNum != -1) {

//                    //顶点是从1开始算,但下标是从0开始
//                    m_adj[this->m_adj[i][0].vNum].push_back(point);
//                }
//            }

            //正左
            if (m_map[this->m_adj[i][0].x][this->m_adj[i][0].y - 1] != -1) {

                Point point = getPointByPosXAndPosY(this->m_adj[i][0].x, this->m_adj[i][0].y - 1);
                if (point.vNum != -1) {

                    //顶点是从1开始算,但下标是从0开始
                    m_adj[this->m_adj[i][0].vNum].push_back(point);
                }
            }
        }
    }


private:
    int m_v;	//顶点的个数
    int m_map[MAX_ROW][MAX_COLUMN];
    QVector<QVector<Point>> m_adj;
};



int main(int argc, char *argv[]) {

    Q_UNUSED(argc)
    Q_UNUSED(argv)

    Graph g(map1);

    g.print();
    g.bfs(0);

    getchar();
    return 0;
}

如下二维棋盘:

int map1[MAX_ROW][MAX_COLUMN] = {
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, 1, -1,
    -1, -1, -1, -1, -1, -1, 0, -1,
    -1, -1, -1, -1, -1, -1, 0, -1,
    -1, -1, -1, -1, -1, -1, 0, -1,
    -1, -1, -1, -1, 1, 1, 0, -1,
    -1, -1, -1, -1, -1, -1, -1, -1
};

BFS是这样的(从第1个顶点(下标为0)开始):

以上是关于C++笔记-二维棋盘数组使用BFS(宽度优先遍历)的主要内容,如果未能解决你的问题,请参考以下文章

C++笔记-基于邻接表的BFS(宽度优先遍历)

C++笔记-二维棋盘数组转邻接表(使用QTL)

算法笔记图结构及图的 DFS 和 BFS 介绍

深度优先遍历(DFS)和广度优先遍历(BFS)

BFS - leetcode [宽度优先遍历]

算法笔记 揭开广度优先遍历BFS的神秘面纱 HERODING的算法之路