首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 二叉樹核心操作完整實現:遍歷、查找、統計、路徑與祖先查詢

     編輯:關於C++

二叉樹節點與類設計

template <typename T>
struct BTNode {
    T data;
    BTNode* lchild;
    BTNode* rchild;
    BTNode(const T& val) : data(val), lchild(nullptr), rchild(nullptr) {}
};

template <typename T>
class BinaryTree {
    BTNode<T>* root;
    // 內部遞歸輔助函數...
public:
    BinaryTree();           // 從標準輸入構建(# 表示空)
    ~BinaryTree();          // 後序釋放

    // 遍歷接口
    void PreOrder()  const { PreOrder(root); }
    void InOrder()   const { InOrder(root); }
    void PostOrder() const { PostOrder(root); }
    void PreOrderIter()  const; // 非遞歸
    void InOrderIter()   const;
    void PostOrderIter() const;
    void LevelOrder()    const; // 層序

    // 查找與統計
    BTNode<T>* FindNode(const T& val) const;
    int Height() const;
    int NodeCount() const;
    void PrintLeaves() const;
    void PrintLeafDepths() const; // 葉子深度
    bool PrintAncestors(const T& val) const; // 祖先路徑
};

樹的構建與銷毀

template <typename T>
BTNode<T>* BinaryTree<T>::CreateTree() {
    T ch; std::cin >> ch;
    if (ch == '#') return nullptr;
    auto* node = new BTNode<T>(ch);
    node->lchild = CreateTree();
    node->rchild = CreateTree();
    return node;
}

template <typename T>
BinaryTree<T>::BinaryTree() : root(CreateTree()) {}

template <typename T>
void BinaryTree<T>::DestroyTree(BTNode<T>* node) {
    if (node) {
        DestroyTree(node->lchild);
        DestroyTree(node->rchild);
        delete node;
    }
}
BinaryTree<T>::~BinaryTree() { DestroyTree(root); }

遞歸遍歷(核心模式)

// 前序:根→左→右
void PreOrder(BTNode<T>* node) {
    if (node) {
        visit(node);
        PreOrder(node->lchild);
        PreOrder(node->rchild);
    }
}

// 中序:左→根→右
void InOrder(BTNode<T>* node) {
    if (node) {
        InOrder(node->lchild);
        visit(node);
        InOrder(node->rchild);
    }
}

// 後序:左→右→根
void PostOrder(BTNode<T>* node) {
    if (node) {
        PostOrder(node->lchild);
        PostOrder(node->rchild);
        visit(node);
    }
}

非遞歸遍歷(顯式棧)

前序:根右左入棧,出棧訪問

void PreOrderIter() const {
    std::stack<BTNode<T>*> st;
    if (root) st.push(root);
    while (!st.empty()) {
        auto* node = st.top(); st.pop();
        visit(node);
        if (node->rchild) st.push(node->rchild);
        if (node->lchild) st.push(node->lchild);
    }
}

中序:沿左鏈入棧,出棧訪問轉右

void InOrderIter() const {
    std::stack<BTNode<T>*> st;
    auto* cur = root;
    while (cur || !st.empty()) {
        while (cur) { st.push(cur); cur = cur->lchild; }
        cur = st.top(); st.pop();
        visit(cur);
        cur = cur->rchild;
    }
}

後序:雙棧法或單棧+前驅標記

void PostOrderIter() const {
    std::stack<BTNode<T>*> st;
    BTNode<T>* cur = root;
    BTNode<T>* prev = nullptr;
    while (cur || !st.empty()) {
        while (cur) { st.push(cur); cur = cur->lchild; }
        cur = st.top();
        if (!cur->rchild || cur->rchild == prev) {
            visit(cur);
            st.pop();
            prev = cur;
            cur = nullptr;
        } else {
            cur = cur->rchild;
        }
    }
}

層序遍歷(隊列)

void LevelOrder() const {
    std::queue<BTNode<T>*> q;
    if (root) q.push(root);
    while (!q.empty()) {
        auto* node = q.front(); q.pop();
        visit(node);
        if (node->lchild) q.push(node->lchild);
        if (node->rchild) q.push(node->rchild);
    }
}

查找與統計操作

BTNode<T>* FindNode(BTNode<T>* node, const T& val) const {
    if (!node) return nullptr;
    if (node->data == val) return node;
    if (auto* p = FindNode(node->lchild, val)) return p;
    return FindNode(node->rchild, val);
}

int Height(BTNode<T>* node) const {
    if (!node) return 0;
    return 1 + std::max(Height(node->lchild), Height(node->rchild));
}

int NodeCount(BTNode<T>* node) const {
    if (!node) return 0;
    return 1 + NodeCount(node->lchild) + NodeCount(node->rchild);
}

葉子節點與路徑深度

void PrintLeaves(BTNode<T>* node) const {
    if (node) {
        if (!node->lchild && !node->rchild) visit(node);
        PrintLeaves(node->lchild);
        PrintLeaves(node->rchild);
    }
}

void PrintLeafDepths(BTNode<T>* node, int depth) const {
    if (!node) return;
    if (!node->lchild && !node->rchild) {
        std::cout << node->data << ": " << depth << '\n';
    }
    PrintLeafDepths(node->lchild, depth+1);
    PrintLeafDepths(node->rchild, depth+1);
}

祖先路徑查詢

bool PrintAncestors(BTNode<T>* node, const T& val) const {
    if (!node) return false;
    if ((node->lchild && node->lchild->data == val) ||
        (node->rchild && node->rchild->data == val) ||
        PrintAncestors(node->lchild, val) ||
        PrintAncestors(node->rchild, val)) {
        visit(node); // 回溯時打印
        return true;
    }
    return false;
}

測試主程序

int main() {
    BinaryTree<char> tree; // 輸入示例:A B D # # E # # C # F # #
    std::cout << "PreOrder: "; tree.PreOrder();
    std::cout << "\nInOrder:  "; tree.InOrder();
    std::cout << "\nPostOrder:"; tree.PostOrder();
    std::cout << "\nLevelOrder:"; tree.LevelOrder();
    std::cout << "\nHeight: " << tree.Height();
    std::cout << "\nNodeCount: " << tree.NodeCount();
    std::cout << "\nLeaves: "; tree.PrintLeaves();
    std::cout << "\nLeafDepths:\n"; tree.PrintLeafDepths();
    std::cout << "Ancestors of E: "; tree.PrintAncestors('E');
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved