#include "Tree_Model.h" #include #include #include namespace Psc { int Node::getDeep() { int ret = -1; Node* cur = static_cast(this); while (cur) { cur = cur->par; ret++; } return ret; } Node::Node() {} int Node::index() { return par->sons.indexOf(static_cast(this)); } bool Node::isRoot() { return par == nullptr; } bool Node::isLeaf() { return !sons.size(); } bool Node::isFirst() { return index() == 0; } bool Node::isLast() { return index() == par->sons.size() - 1; } Node* Node::previous() { if (isFirst()) return nullptr; return par->sons[index() - 1]; } Node* Node::next() { if (isLast()) return nullptr; return par->sons[index() + 1]; } Node* Node::lastChild() { if (isLeaf()) std::cout << "lastChild() error"; return sons[sons.size() - 1]; } Node* Node::firstChild() { if (isLeaf()) std::cout << "firstChild() error"; return sons[0]; } Node* Node::root() { Node* ret = static_cast(this); while (ret->par != nullptr) { ret = ret->par; } return ret; } QVector Node::deepTraversed() { QVector result; if (!this) return result; QStack stack; stack.push(this); while (!stack.isEmpty()) { Node* node = stack.pop(); result.append(node); // 逆序压入子节点,保证从左到右的遍历顺序 for (int i = node->sons.size() - 1; i >= 0; --i) { stack.push(node->sons[i]); } } return result; } QVector Node::sequenceTraversed() { QVector ret; QQueue que; Node* that = this; que.enqueue(that); while (!que.empty()) { Node* cur = que.dequeue(); int n = cur->sons.size(); ret.append(cur); for (int i = 0; i < n; ++i) { que.enqueue(cur->sons[i]); } } return ret; } QVector Node::descendants() { QVector&& ret = sequenceTraversed(); ret.pop_front(); return ret; } QVector deepTraversed(const QVector& nodes) { QVector result; if (nodes.isEmpty()) return result; QStack stack; for (Node* node : nodes) { if (node) stack.push_front(node); } while (!stack.isEmpty()) { Node* node = stack.pop(); result.append(node); // 逆序压入子节点,保证从左到右的遍历顺序 for (int i = node->sons.size() - 1; i >= 0; --i) { stack.push(node->sons[i]); } } return result; } #define ReMain (pos - total_height) int Tree_Model::height() { int total_height = 0; QStack> stack; for (Node* node : roots) { if (node) stack.push_front({node, 0}); } Node* cur{}; int deep{}; while (!stack.isEmpty()) { auto t = stack.top(); cur = t.first; deep = t.second; stack.pop(); if (cur->expand) { for (int i = cur->sons.size() - 1; i >= 0; --i) { stack.push({cur->sons[i], deep + 1}); } } total_height += cur->height + space; } return total_height; } Tree_Pos get_pos(int pos, const QVector& roots, int space) { int total_height = 0; QStack> stack; for (Node* node : roots) { if (node) stack.push_front({node, 0}); } Node* cur{}; int deep{}; while (!stack.isEmpty()) { auto t = stack.top(); cur = t.first; deep = t.second; if (ReMain < cur->height) { return Tree_Pos{cur, deep, total_height, ReMain, stack}; } stack.pop(); if (cur->expand) { for (int i = cur->sons.size() - 1; i >= 0; --i) { stack.push({cur->sons[i], deep + 1}); } } total_height += cur->height + space; } return Tree_Pos{cur, deep, total_height, ReMain, stack}; } void select_node(const QVector& roots, int view_y, int length, int space, Node_Call_Back call_back) { auto ret = get_pos(view_y, roots, space); QStack>& stack = ret.rest; int cur_inside_y = ret.node_pos; int cur_inside_end = cur_inside_y + length; while (!stack.isEmpty()) { auto [cur, depth] = stack.pop(); if (cur->expand) { for (int i = cur->sons.size() - 1; i >= 0; --i) { stack.push({cur->sons[i], depth + 1}); } } call_back(cur, depth, cur_inside_y); cur_inside_y += cur->height + space; if (cur_inside_y > cur_inside_end) { break; } } } }