实现在一个十字链表中删去非0元素
时间: 2024-05-14 21:15:00 浏览: 23
假设十字链表的节点结构如下:
```
struct Node {
int row, col, val;
Node* right;
Node* down;
};
```
其中 `row` 和 `col` 分别表示节点所在的行和列,`val` 表示节点的值,`right` 和 `down` 分别指向节点的右侧和下方节点。
我们可以分别遍历每一行和每一列,并且在遍历时记录上一个非零节点和当前节点,如果当前节点的值为 0,则将上一个非零节点的 `right` 或 `down` 指针指向当前节点的下一个节点,从而实现删除当前节点。
具体实现如下:
```
void removeNonZero(Node* head) {
Node* prevRow[MaxSize] = {}; // 记录上一个非零节点
Node* prevCol[MaxSize] = {};
for (Node* rowNode = head->down; rowNode != head; rowNode = rowNode->down) {
Node* prev = rowNode;
for (Node* colNode = rowNode->right; colNode != rowNode; colNode = colNode->right) {
if (colNode->val == 0) {
// 将上一个非零节点的 right 指向当前节点的下一个节点
prev->right = colNode->right;
} else {
// 更新 prev
prev = colNode;
}
}
// 记录最后一个非零节点
prevRow[rowNode->row] = prev;
}
for (Node* colNode = head->right; colNode != head; colNode = colNode->right) {
Node* prev = colNode;
for (Node* rowNode = colNode->down; rowNode != colNode; rowNode = rowNode->down) {
if (rowNode->val == 0) {
// 将上一个非零节点的 down 指向当前节点的下一个节点
prev->down = rowNode->down;
} else {
// 更新 prev
prev = rowNode;
}
}
// 记录最后一个非零节点
prevCol[colNode->col] = prev;
}
// 处理横向链表中的零节点
for (Node* rowNode = head->down; rowNode != head; rowNode = rowNode->down) {
if (rowNode->right == rowNode) {
// 如果这一行只有一个节点,说明这个节点的值为 0,直接删除
rowNode->down->up = rowNode->up;
rowNode->up->down = rowNode->down;
} else {
// 如果这一行有多个节点,需要判断第一个节点是否为零节点
if (rowNode->right->val == 0) {
// 如果第一个节点是零节点,将链表头指向第二个节点
rowNode->right = rowNode->right->right;
}
}
}
// 处理纵向链表中的零节点
for (Node* colNode = head->right; colNode != head; colNode = colNode->right) {
if (colNode->down == colNode) {
// 如果这一列只有一个节点,说明这个节点的值为 0,直接删除
colNode->right->left = colNode->left;
colNode->left->right = colNode->right;
} else {
// 如果这一列有多个节点,需要判断第一个节点是否为零节点
if (colNode->down->val == 0) {
// 如果第一个节点是零节点,将链表头指向第二个节点
colNode->down = colNode->down->down;
}
}
}
// 处理横向链表中的非零节点
for (int i = 1; i <= n; i++) {
if (prevRow[i] != nullptr && prevRow[i]->right == head->right) {
// 如果这一行的第一个节点是非零节点,需要将链表头指向这个节点
prevRow[i]->right = head;
}
}
// 处理纵向链表中的非零节点
for (int j = 1; j <= m; j++) {
if (prevCol[j] != nullptr && prevCol[j]->down == head->down) {
// 如果这一列的第一个节点是非零节点,需要将链表头指向这个节点
prevCol[j]->down = head;
}
}
}
```