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

Posted IT1995

tags:

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

使用这样的结构存储邻接表:

QVector<QVector<Point>> m_adj;

Point存储当前顶点号及X轴,Y轴:

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轴
};

这里棋盘是这样的,如下:

#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, 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, 0, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1
};

这里的算法很简单:

//左上
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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].push_back(point);
     }
}

程序运行截图如下;

这样的棋盘:

int map1[MAX_ROW][MAX_COLUMN] = {
    -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, 0, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -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, 0, 1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1
};

运行截图如下:

完整源码如下:

#include <QDebug>
#include <QVector>

#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, 0, 1, -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轴
};

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() << "------------------------------------";
        }
    }

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);
    }

    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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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 - 1].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[]) {

    Graph g(map1);

    g.print();

    getchar();
    return 0;
}

还有一种是用-1包住棋盘,这样就更加方便了,在下一篇笔记中将会说明!

以上是关于C++笔记-二维棋盘数组转邻接表(使用QTL)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

如何使 c++ 代码既可用于 Qt 项目(QTL 风格)也可用于 C++ 项目(STL 风格)

二维数组转稀疏数组,写入文件后再读取文件,将内容转回二维数组

(王道408考研数据结构)第六章图-第二节1:图的存储结构(邻接矩阵邻接表十字链表和邻接多重表)

使用邻接表在 C++ 中实现 DFS(使用 <vector> 和链表)