|
|
- //
- // Created by 423A35C7 on 2023-11-12.
- //
-
- // #include <functional>
- // #include <list>
- #include <cassert>
- #include <queue>
- #include <string>
-
- struct Node {
- int num = 0;
- std::string text;
- // 线索化的标记
- bool if_left_chain = false;
- bool if_right_chain = false;
- // 左右子树或前驱后继
- Node* left = nullptr;
- Node* right = nullptr;
-
- Node(int num, const std::string& text)
- : num(num),
- text(text) {
- }
-
- ~Node() {
- remove_left();
- remove_right();
- }
-
- void remove_left() {
- if (left != nullptr && !if_left_chain) {
- // delete the node
- left->~Node();
- // delete the memory
- delete left;
- // set the pointer to nullptr
- left = nullptr;
- }
- }
-
- void remove_right() {
- if (right != nullptr && !if_right_chain) {
- // delete the node
- right->~Node();
- // delete the memory
- delete right;
- // set the pointer to nullptr
- right = nullptr;
- }
- }
-
- };
- class BiTree {
- Node *find(int num) {
- Node *temp;
- // 遍历查找num
- for (temp = head; temp && temp->num < num; temp = temp->right);
- return temp;
- }
-
- void insert_left(Node *parent, const std::string& text) {
- // 断言parent不为空
- assert(parent != nullptr);
- // parent->remove_left();
- // 如果parent->left为空,则插入新节点
- if (parent->left == nullptr)
- parent->left = new Node {0, text};
- else
- insert_right(parent->left, text);
- }
-
- void insert_right(Node *parent, const std::string& text) {
- // 断言parent不为空
- assert(parent != nullptr);
- // 记录tail
- Node *tail = parent;
- // 遍历查找tail->right
- for (; !tail->if_right_chain && tail->right; tail = tail->right);
- // 插入新节点
- tail->right = new Node {0, text};
- tail->if_right_chain = false;
- }
- public:
- Node *head;
- int length = 0;
- BiTree() {
- // 初始化头节点
- this->head = new Node(0, "");
- // 初始化节点数量
- this->length = 1;
- }
- ~BiTree() {
- // 删除头节点的左右子节点
- this->head->remove_left();
- this->head->remove_right();
- // 删除头节点
- delete this->head;
- }
-
- void update() {
- // 左节点入队,出队时扩展到所有的右节点
- std::queue<Node*> q;
- Node *current = head, *next = head->left;
- int current_num = 0;
- // while (!q.empty()) {
- // current->if_right_chain = true;
- // current->right = q.front();
- // current = q.front();
- // q.pop();
- // Node *next = current;
- // for (; next && !next->if_right_chain; current = next, next = next->right) {
- // next->num = current_num++;
- // if (next->left) {
- // q.push(next->left);
- // }
- // }
- // 当前节点为空,则跳出循环
- while (current) {
- // 当前节点的编号
- current->num = current_num++;
- // 如果当前节点有左子节点,则将左子节点放入队列
- if (current->left) {
- q.push(current->left);
- }
-
- // 发生间断,从队列中重新取值
- if (!current->right || current->if_right_chain) {
- // 如果当前节点没有右子节点,或者当前节点已经处理完右子节点,则跳出循环
- if (q.empty()) break;
- // 从队列中取出下一个节点
- next = q.front();
- // 从队列中删除该节点
- q.pop();
- // 标记当前节点是线索化右子节点
- current->if_right_chain = true;
- } else {
- // 标记当前节点不是线索化右子节点
- current->if_right_chain = false;
- }
- // 将当前节点的右子节点设置为下一个节点
- current->right = next;
- // 将当前节点设置为下一个节点
- current = next;
- // 将下一个节点设置为下一个节点的右子节点
- next = next->right;
- }
- // 更新树的层数
- this->length = current_num;
- }
-
- void insert(int num, std::queue<std::string> &children) {
- // 找到要插入的父节点
- Node *parent = this->find(num);
- // 断言父节点不为空
- assert(parent != nullptr);
- // 如果子节点为空,则直接返回
- if (children.empty()) return;
- // 插入左子节点
- this->insert_left(parent, children.front());
- // 从队列中弹出第一个子节点
- children.pop();
- // 将父节点指向左子节点
- parent = parent->left;
- // 如果队列不为空,则插入右子节点
- while (!children.empty()) {
- this->insert_right(parent, children.front());
- // 从队列中弹出第一个子节点
- children.pop();
- // 将父节点指向右子节点
- parent = parent->right;
- }
- // 更新树的序号
- this->update();
- }
- };
-
|