平衡树可以用迭代写吗,请写出代码
时间: 2024-05-01 15:20:15 浏览: 35
c++avl平衡树,实现插入删除功能,可以实现但是未实现迭代器以及第查询第k个数的功能。
平衡树可以用迭代方式进行实现,以下是一个基于红黑树的迭代式实现示例:
```C++
#include <iostream>
#include <stack>
using namespace std;
enum Color { RED, BLACK };
struct Node {
int val;
Color color;
Node *left, *right, *parent;
Node(int val) : val(val), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};
class RBTree {
public:
RBTree() : root(nullptr) {}
void insert(int val) {
Node *node = new Node(val);
if (root == nullptr) {
root = node;
node->color = BLACK;
return;
}
Node *parent = nullptr, *cur = root;
while (cur != nullptr) {
parent = cur;
if (val < cur->val) {
cur = cur->left;
} else {
cur = cur->right;
}
}
node->parent = parent;
if (val < parent->val) {
parent->left = node;
} else {
parent->right = node;
}
insertFixup(node);
}
void erase(int val) {
Node *node = search(val);
if (node == nullptr) return;
Node *child = nullptr;
if (node->left == nullptr || node->right == nullptr) {
child = node;
} else {
child = node->right;
while (child->left != nullptr) {
child = child->left;
}
}
Node *sibling = child->left != nullptr ? child->left : child->right;
if (sibling != nullptr) {
sibling->parent = child->parent;
}
if (child->parent == nullptr) {
root = sibling;
} else {
if (child == child->parent->left) {
child->parent->left = sibling;
} else {
child->parent->right = sibling;
}
}
if (child != node) {
node->val = child->val;
}
if (child->color == BLACK) {
eraseFixup(sibling, child->parent);
}
delete child;
}
Node* search(int val) {
Node *cur = root;
while (cur != nullptr) {
if (val == cur->val) {
return cur;
} else if (val < cur->val) {
cur = cur->left;
} else {
cur = cur->right;
}
}
return nullptr;
}
void print() {
if (root == nullptr) {
cout << "Empty tree." << endl;
return;
}
stack<pair<Node*, int>> st;
st.push({root, 0});
while (!st.empty()) {
Node *cur = st.top().first;
int cnt = st.top().second;
st.pop();
for (int i = 0; i < cnt; i++) {
cout << " ";
}
cout << cur->val << " (" << (cur->color == RED ? "red" : "black") << ")" << endl;
if (cur->right != nullptr) {
st.push({cur->right, cnt+1});
}
if (cur->left != nullptr) {
st.push({cur->left, cnt+1});
}
}
}
private:
Node *root;
void leftRotate(Node *node) {
Node *right = node->right;
node->right = right->left;
if (right->left != nullptr) {
right->left->parent = node;
}
right->parent = node->parent;
if (node->parent == nullptr) {
root = right;
} else {
if (node == node->parent->left) {
node->parent->left = right;
} else {
node->parent->right = right;
}
}
right->left = node;
node->parent = right;
}
void rightRotate(Node *node) {
Node *left = node->left;
node->left = left->right;
if (left->right != nullptr) {
left->right->parent = node;
}
left->parent = node->parent;
if (node->parent == nullptr) {
root = left;
} else {
if (node == node->parent->left) {
node->parent->left = left;
} else {
node->parent->right = left;
}
}
left->right = node;
node->parent = left;
}
void insertFixup(Node *node) {
while (node->parent != nullptr && node->parent->color == RED) {
if (node->parent == node->parent->parent->left) {
Node *uncle = node->parent->parent->right;
if (uncle != nullptr && uncle->color == RED) {
node->parent->color = BLACK;
uncle->color = BLACK;
node->parent->parent->color = RED;
node = node->parent->parent;
} else {
if (node == node->parent->right) {
node = node->parent;
leftRotate(node);
}
node->parent->color = BLACK;
node->parent->parent->color = RED;
rightRotate(node->parent->parent);
}
} else {
Node *uncle = node->parent->parent->left;
if (uncle != nullptr && uncle->color == RED) {
node->parent->color = BLACK;
uncle->color = BLACK;
node->parent->parent->color = RED;
node = node->parent->parent;
} else {
if (node == node->parent->left) {
node = node->parent;
rightRotate(node);
}
node->parent->color = BLACK;
node->parent->parent->color = RED;
leftRotate(node->parent->parent);
}
}
}
root->color = BLACK;
}
void eraseFixup(Node *node, Node *parent) {
while (node != root && (node == nullptr || node->color == BLACK)) {
if (node == parent->left) {
Node *sibling = parent->right;
if (sibling->color == RED) {
sibling->color = BLACK;
parent->color = RED;
leftRotate(parent);
sibling = parent->right;
}
if ((sibling->left == nullptr || sibling->left->color == BLACK) && (sibling->right == nullptr || sibling->right->color == BLACK)) {
sibling->color = RED;
node = parent;
parent = parent->parent;
} else {
if (sibling->right == nullptr || sibling->right->color == BLACK) {
sibling->color = RED;
sibling->left->color = BLACK;
rightRotate(sibling);
sibling = parent->right;
}
sibling->color = parent->color;
parent->color = BLACK;
sibling->right->color = BLACK;
leftRotate(parent);
node = root;
break;
}
} else {
Node *sibling = parent->left;
if (sibling->color == RED) {
sibling->color = BLACK;
parent->color = RED;
rightRotate(parent);
sibling = parent->left;
}
if ((sibling->left == nullptr || sibling->left->color == BLACK) && (sibling->right == nullptr || sibling->right->color == BLACK)) {
sibling->color = RED;
node = parent;
parent = parent->parent;
} else {
if (sibling->left == nullptr || sibling->left->color == BLACK) {
sibling->color = RED;
sibling->right->color = BLACK;
leftRotate(sibling);
sibling = parent->left;
}
sibling->color = parent->color;
parent->color = BLACK;
sibling->left->color = BLACK;
rightRotate(parent);
node = root;
break;
}
}
}
if (node != nullptr) {
node->color = BLACK;
}
}
};
int main() {
RBTree tree;
tree.insert(5);
tree.insert(10);
tree.insert(1);
tree.insert(8);
tree.insert(3);
tree.insert(6);
tree.insert(7);
tree.insert(2);
tree.insert(4);
tree.print();
tree.erase(5);
tree.print();
return 0;
}
```
在这个示例中,我们使用了颜色枚举类型和节点结构体来表示红黑树中的节点,同时实现了插入、删除和查找操作。在插入和删除操作中,我们使用了插入修复和删除修复的算法来保证红黑树的性质。在输出树的结构时,我们使用了一个栈来模拟递归的过程,从而实现了迭代式的遍历。
阅读全文