(在线显示未通过的数据在我自己的IDE(Xcode)上运行结果正确,暂未找到原因,在此记录代码)
int len = 0; //记录优先队列长度
int v = 0; //记录体积
int top = 0; //记录周围最大高度
typedef struct mapNode{
int x;
int y;
int data;
bool visit;
}Map;
typedef struct qNode{
Map point;
struct qNode *next;
}Queue;
void inQueue(Map map[], Queue *q, int mx, int my, int mdata, int heightMapColSize){
//声明和初始化游标指针
Queue *r;
r = q;
//创建和初始化待插入节点
Queue *p = (Queue*)malloc(sizeof(Queue));
p -> point.x = mx;
p -> point.y = my;
p -> point.data = mdata;
p -> next = NULL;
//更新Map数组visit
map[mx * heightMapColSize + my].visit = true;
//若为空表直接插入
if(q -> next == NULL) r -> next = p;
//非空表升按序插入
else{
while(r -> next && r -> next -> point.data <= mdata) r = r -> next;
p -> next = r -> next;
r -> next = p;
}
++len;
}
void deQueue(Queue *q){
Queue *tmp;
tmp = q -> next;
q -> next = tmp -> next;
if(tmp){
free(tmp);
--len;
}
}
void getIn(Map map[], Queue *q, int heightMapRowSize,int heightMapColSize){
int t_x = q -> next -> point.x;
int t_y = q -> next -> point.y;
top = q -> next -> point.data > top ? q -> next -> point.data : top;
//该点visit值置true并将其从优先队列中删除
map[t_x * heightMapColSize + t_y].visit = true;
deQueue(q);
//依次遍历该点上下左右的四个点,若超出map边界或已访问,跳过
//若满足待访问条件的周围点比当前top小,将差值加入v
//将满足待访问条件的周围点插入优先队列
int addx[4] = {-1, 1, 0, 0};
int addy[4] = {0, 0, -1, 1};
for(int i = 0; i < 4; ++i){
int n_x = t_x + addx[i];
int n_y = t_y + addy[i];
int pos = n_x * heightMapColSize + n_y;
if(map[pos].visit == true || n_x < 0 || n_y < 0 ||
n_x >= heightMapRowSize || n_y >= heightMapColSize)
continue;
else{
if(map[pos].data < top)
v += top - map[pos].data;
inQueue(map, q, n_x, n_y, map[pos].data, heightMapColSize);
}
}
}
int trapRainWater(int **heightMap, int heightMapRowSize, int heightMapColSize) {
if(heightMap == NULL || heightMapRowSize == 0 || heightMapColSize == 0)
return 0;
int i, j;
Queue *queue = (Queue*)malloc(sizeof(Queue)); //建立优先队列的头节点
queue -> next = NULL;
//声明并初始化map结构体数组(标记图中各点是否已被访问)
Map map[heightMapRowSize * heightMapColSize];
for(i = 0; i < heightMapRowSize; ++i)
for(j = 0; j < heightMapColSize; ++j){
int pos = i * heightMapColSize + j;
map[pos].x = i;
map[pos].y = j;
map[pos].data = heightMap[i][j];
map[pos].visit = false;
}
//将最外圈各点输入
for(i = 0; i < heightMapRowSize; ++i){
inQueue(map, queue, i, 0, heightMap[i][0], heightMapColSize);
inQueue(map, queue, i, heightMapColSize - 1, heightMap[i][heightMapColSize - 1], heightMapColSize);
}
for(j = 1; j < heightMapColSize - 1; ++j){
inQueue(map, queue, 0, j, heightMap[0][j], heightMapColSize);
inQueue(map, queue, heightMapRowSize - 1, j, heightMap[heightMapRowSize - 1][j], heightMapColSize);
}
//不断选取边界最低点向内收缩
while(len){
getIn(map, queue, heightMapRowSize, heightMapColSize);
// Queue *p = queue -> next;
// for(i = 0; i < len; ++i){
// printf("(%d,%d):%d ", p -> point.x, p -> point.y, p -> point.data);
// p = p -> next;
// }
// printf("\n");
}
return v;
}