隨便寫的一點BinTree模板實現

superb24ed發表於2024-11-02

`#pragma warning(disable : 4996)

include

include

include

include

template
struct BinNode {
int _depth; // 節點深度
int _height; // 節點高度
T _data; // 儲存的資料
BinNode* _parent; // 父節點
BinNode* _lChild; // 左子節點
BinNode* _rChild; // 右子節點

template <typename VST> static  void visitAlongLeftBranch(BinNode* x, VST&, std::stack<BinNode*>& s);

public:
BinNode();
BinNode(const T& data);
int size() const; // 獲取當前節點及其所有後代節點的總數
BinNode* succ() const; // 獲取中序遍歷下的後繼節點
template void travLevel(VST&); // 層次遍歷
template void travPre(VST&); // 先序遍歷(迭代)
template static void travPre_I2(BinNode* x,VST&); // 先序遍歷(迭代)
template void travIn(VST&); // 中序遍歷(迭代)
template void travPost(VST&); // 後序遍歷(迭代)
};

template
BinNode::BinNode() : _depth(0), _height(0), _data(T()), _parent(nullptr), _lChild(nullptr), _rChild(nullptr) {}

template
BinNode::BinNode(const T& data) : _depth(0), _height(0), _data(data), _parent(nullptr), _lChild(nullptr), _rChild(nullptr) {}

template
int BinNode::size() const {
return (_lChild ? _lChild->size() : 0) + (_rChild ? _rChild->size() : 0) + 1;
}

template
BinNode* BinNode::succ() const {
BinNode* p = const_cast<BinNode*>(this);
if (_rChild) {
p = _rChild;
while (p->_lChild) p = p->_lChild;
}
else {
while (p->_parent && p == p->_parent->_rChild) p = p->_parent;
p = p->_parent;
}
return p;
}

template
template
void BinNode::travLevel(VST& visit) {
std::queue<BinNode> q;
q.push(this);
while (!q.empty()) {
BinNode
x = q.front(); q.pop();
visit(x->_data);
if (x->_lChild) q.push(x->_lChild);
if (x->_rChild) q.push(x->_rChild);
}
}

template
template
void BinNode::visitAlongLeftBranch(BinNode* x, VST& visit, std::stack<BinNode *> &s)
{
while (!x) {
visit(x);
x = x->_lChild;
s.push(_rChild);
}

}

template
template
void BinNode::travPre(VST& visit) {
std::stack<BinNode> s; // 建立棧
s.push(this); // 將根節點壓入棧中
while (!s.empty()) {
BinNode
x = s.top(); // 取棧頂元素
s.pop(); // 彈出棧頂元素
visit(x->_data); // 訪問該節點
if (x->_rChild) s.push(x->_rChild); // 先壓右子節點,後壓左子節點
if (x->_lChild) s.push(x->_lChild);
}
}

template
template
static void BinNode::travPre_I2(BinNode* x,VST& visit)
{
std::stack<BinNode *> s;
while (true) {
visitAlongLeftBranch(this, visit, s);
if (s.empty()) break;
x = s.top();
}
}

template
template
void BinNode::travIn(VST& visit) {
std::stack<BinNode> s; // 建立棧
BinNode
current = this; // 從當前節點開始
while (current != nullptr || !s.empty()) {
while (current != nullptr) { // 遍歷左子樹
s.push(current); // 將當前節點壓入棧中
current = current->_lChild; // 移動到左子節點
}
if (!s.empty()) {
current = s.top(); // 訪問棧頂元素
s.pop(); // 彈出棧頂元素
visit(current->_data); // 訪問該節點
current = current->_rChild; // 轉向右子節點
}
}
}

template
template
void BinNode::travPost(VST& visit) {
std::stack<BinNode> s1, s2; // 建立兩個棧
s1.push(this); // 將根節點壓入第一個棧
while (!s1.empty()) {
BinNode
x = s1.top();
s1.pop();
s2.push(x); // 將節點壓入第二個棧
if (x->_lChild) s1.push(x->_lChild); // 先壓左子節點
if (x->_rChild) s1.push(x->_rChild); // 再壓右子節點
}
while (!s2.empty()) { // 訪問第二個棧中的節點
visit(s2.top()->_data);
s2.pop();
}
}

template
class BinTree {
protected:
int _size; // 節點數
BinNode* _root; // 根節點

virtual int updateHeight(BinNode<T>* x);            // 更新節點高度
void updateHeightAbove(BinNode<T>* x);      // 更新當前節點及其所有祖先的高度
void release(BinNode<T>* x);                // 遞迴釋放節點記憶體

virtual int updateDepth(BinNode<T>* x);            // 更新節點深度
void updateDepthBelow(BinNode<T>* x);      // 更新當前節點及其所有子節點的深度

public:
BinTree() : _size(0), _root(nullptr) {}
~BinTree(); // 解構函式
int size() const { return _size; }
bool empty() const { return !_root; }
BinNode* root() const { return _root; }

BinNode<T>* insertAsRoot(const T& elem);    // 插入根節點
BinNode<T>* insertAsLC(BinNode<T>* parent, const T& elem);  // 插入左子節點
BinNode<T>* insertAsRC(BinNode<T>* parent, const T& elem);  // 插入右子節點

};

template
int BinTree::updateHeight(BinNode* x) {
return x->_height = 1 + std::max(x->_lChild ? x->_lChild->_height : -1,
x->_rChild ? x->_rChild->_height : -1);
}

template
void BinTree::updateHeightAbove(BinNode* x) {
while (x) {
int oldHeight = x->_height; // 儲存舊高度
updateHeight(x);
if (oldHeight == x->_height) { // 如果高度沒有變化
break; // 提前終止更新
}
x = x->_parent;
}
}

template
int BinTree::updateDepth(BinNode* x) {
if (x == nullptr) return -1; // 深度以-1開始
x->_depth = x->_parent ? x->_parent->_depth + 1 : 0; // 更新深度
return x->_depth;
}

template
void BinTree::updateDepthBelow(BinNode* x) {
if (x) {
int oldDepth = x->_depth; // 儲存舊深度
updateDepth(x); // 更新當前節點的深度
if (oldDepth == x->_depth) { // 如果深度沒有變化
return; // 提前終止更新
}
updateDepthBelow(x->_lChild); // 遞迴更新左子節點深度
updateDepthBelow(x->_rChild); // 遞迴更新右子節點深度
}
}

template
void BinTree::release(BinNode* x) {
if (x) {
release(x->_lChild); // 釋放左子節點
release(x->_rChild); // 釋放右子節點
delete x; // 釋放當前節點
}
}

template
BinTree::~BinTree() {
release(_root); // 釋放根節點及其所有子節點
}

template
BinNode* BinTree::insertAsRoot(const T& elem) {
_root = new BinNode(elem);
_size = 1;
updateDepthBelow(_root); // 更新深度
return _root;
}

template
BinNode* BinTree::insertAsLC(BinNode* parent, const T& elem) {
if (!parent->_lChild) {
parent->_lChild = new BinNode(elem);
parent->_lChild->_parent = parent;
_size++;
updateHeightAbove(parent); // 更新高度
updateDepthBelow(parent->_lChild); // 更新深度
return parent->_lChild;
}
return nullptr; // 返回空表示插入失敗
}

template
BinNode* BinTree::insertAsRC(BinNode* parent, const T& elem) {
if (!parent->_rChild) {
parent->_rChild = new BinNode(elem);
parent->_rChild->_parent = parent;
_size++;
updateHeightAbove(parent); // 更新高度
updateDepthBelow(parent->_rChild); // 更新深度
return parent->_rChild;
}
return nullptr; // 返回空表示插入失敗
}

void visit(int& e) { std::cout << e << " "; }

int main() {
BinTree tree;
BinNode* root = tree.insertAsRoot(1);
BinNode* leftChild = tree.insertAsLC(root, 2);
BinNode* rightChild = tree.insertAsRC(root, 3);
tree.insertAsLC(leftChild, 4);
tree.insertAsRC(leftChild, 5);
tree.insertAsLC(rightChild, 6);
tree.insertAsRC(rightChild, 7);

std::cout << "Level Order: ";
root->travLevel(visit);
std::cout << "\nPre-order: ";
root->travPre(visit);
std::cout << "\nIn-order: ";
root->travIn(visit);
std::cout << "\nPost-order: ";
root->travPost(visit);
std::cout << std::endl;

return 0;

}
`

相關文章