#include <iostream>
using namespace std;
struct fourTreeNode {
bool isLeaf; //是否叶子结点标识符
int val; //结点值
fourTreeNode* children[4]; //指向四个子树的指针
fourTreeNode(bool leaf, int value) : isLeaf(leaf), val(value) { //对叶子结点的构造函数
for (int i = 0; i < 4; i++) {
children[i] = nullptr;
}
}
};
//使用给定二维数组对四叉树进行构建
fourTreeNode* buildTree(int** grid, int x, int y, int size) {
//grid:给定二维数组 x,y:标定了当前子区域的起始位置,如整个数组左上角 其对应x y都为0 size:需构建区域大小
if (size == 1) { //size为1 即为叶子结点时
return new fourTreeNode(true, grid[x][y]);
}
fourTreeNode* node = new fourTreeNode(false, 0); //其他情况则还有需要构建的子结点
int newSize = size / 2; //每构建一次 需构建区域大小变为原来一半
node->children[0] = buildTree(grid, x, y, newSize);
node->children[1] = buildTree(grid, x, y + newSize, newSize);
node->children[2] = buildTree(grid, x + newSize, y, newSize);
node->children[3] = buildTree(grid, x + newSize, y + newSize, newSize);
//x和y参数会根据当前子区域的位置进行更新。例如,当递归构建左上子区域时,x和y参数保持不变;当递归构建右上子区域时,
//x保持不变,而y增加了当前子区域的大小,以确定右上子区域在原始二维数组中的位置。
if (node->children[0]->isLeaf && node->children[1]->isLeaf && //当四个孩子结点值相同时合并为同一结点
node->children[2]->isLeaf && node->children[3]->isLeaf &&
node->children[0]->val == node->children[1]->val &&
node->children[0]->val == node->children[2]->val &&
node->children[0]->val == node->children[3]->val) {
node->isLeaf = true;
node->val = node->children[0]->val;
for (int i = 0; i < 4; i++) {
delete node->children[i];
node->children[i] = nullptr;
}
}
return node;
}
void printTree(fourTreeNode* root) {
if (root == nullptr) {
return;
}
if (root->isLeaf) {
cout << root->val << " ";
}
else {
cout << "[ ";
for (int i = 0; i < 4; i++) {
printTree(root->children[i]);
}
cout << "] ";
}
}
int main() {
int n;
cout << "请输入二维数组的大小 n:";
cin >> n;
int** grid = new int* [n];
for (int i = 0; i < n; i++) {
grid[i] = new int[n];
}
cout << "请输入二维数组的元素:" << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> grid[i][j];
}
}
fourTreeNode* root = buildTree(grid, 0, 0, n);
cout << "四叉树压缩结果:" << endl;
printTree(root);
cout << endl;
// 释放内存
for (int i = 0; i < n; i++) {
delete[] grid[i];
}
delete[] grid;
return 0;
}
代码如上,总体思路同二叉树,难点在于读取二位数组部分的理解,后续更新详细注释~