// // Created by 423A35C7 on 2023-11-12. // // #include // #include #include #include #include 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 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 &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(); } };