1. 程式人生 > >C++實現二叉排序樹

C++實現二叉排序樹

1.定義

二叉排序樹(Binary Sort Tree),又稱二叉查詢樹(Binary Search Tree),亦稱二叉搜尋樹。

二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹: (1)若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; (2)若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; (3)左、右子樹也分別為二叉排序樹; (4)沒有鍵值相等的節點。

 

簡言之,左子樹小於父節點,右子樹大於父節點的二叉樹就是二叉排序樹  

2.程式碼實現

遞迴插入: 判斷當前結點是否是空指標,是則呼叫構造方法 當前結點不為空,和待插入引數obj進行比較,obj小於當前結點權值,遞迴插入左子樹;obj大於當前結點權值,遞迴插入右子樹 當前結點等於結點權值,不做處理
    template <typename T>
    void
BinarySearchTree<T>::__insert(BinaryNode * & node, const T & obj) { if (node == nullptr) { node = new BinaryNode(obj, nullptr, nullptr); } else if (obj < node->element) { __insert(node->left, obj); }
else if (obj > node->element) { __insert(node->right, obj); } else { //ignore case of duplicate } }

 迭代插入:

先判斷當前結點是否為空,同上

設定flag標記,進入while迴圈,obj小於當前結點權值,左子樹為空則為左子樹例項化BinaryNode,否則左子樹賦給當前結點,相當於當前結點往左下方移動

同理,obj大於當前結點權值,右子樹為空則為右子樹例項化BinaryNode,否則右子樹賦給當前結點,相當於當前結點往右下方移動

當前結點等於結點權值,flag置為false,結束while迴圈

    template <typename T>
    void BinarySearchTree<T>::__insert(BinaryNode * & node, T && obj)
    {
        if (node == nullptr) {
            node = new BinaryNode(std::move(obj), nullptr, nullptr);
            return;
        }
        BinaryNode * currNode = node;
        bool flag = true;
        while (flag) {
            if (currNode->element > obj) {
                if (currNode->left == nullptr) {
                    currNode->left = new BinaryNode(std::move(obj), nullptr, nullptr);
                    flag = false;
                }
                else {
                    currNode = currNode->left;
                }
            }
            else if (currNode->element < obj) {
                if (currNode->right == nullptr) {
                    currNode->right = new BinaryNode(std::move(obj), nullptr, nullptr);
                    flag = false;
                }
                else {
                    currNode = currNode->right;
                }
            }
            else {
                flag = false;
                //case of duplicate
            }
        }
    }

 刪除元素:

判斷當前結點是否為空

obj小於當前結點權值,左子樹遞迴呼叫__remove,直到當前結點為空,return結束;obj大於當前結點權值,右子樹遞迴呼叫__remove,直到當前結點為空,return結束

當obj和當前結點權值相等時

判斷左子樹和右子樹是否同時為空指標

未完待續。。。。。。

    template <typename T>
    void BinarySearchTree<T>::__remove(BinaryNode *node, const T & obj) {
        if (node == nullptr) {
            return;
        }

        if (obj < node->element) {
            __remove(node->left, obj);
        }
        else if (obj > node->element) {
            __remove(node->right, obj);
        }
        else {
            if (node->left != nullptr &&
                node->right != nullptr) {
                node->element = __findMin(node->right)->element;
                __remove(node->right, node->element);
            }
            else {
                BinaryNode *oldNode = node;
                node = (node->left != nullptr) ? node->left : node->right;
                delete oldNode;
            }

        }
    }

 程式碼:https://github.com/cjy513203427/C_Program_Base/tree/master/60.%E4%BA%8C%E5%8F%89%E6%8E%92%E5%BA%8F%E6%A0%91