二叉查找樹C++實現

二分查找樹特色:node

(1) 若任意節點的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值;ios

(2) 任意節點的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值;ide

(3) 任意節點的左、右子樹也分別爲二叉查找樹。post

(4) 沒有鍵值相等的節點(no duplicate nodes)。spa

前序遍歷:中左右3d

中序遍歷:左中右code

序遍歷:左右中blog

二叉查找樹的重點在於如何找節點的前驅節點和後繼節點排序

#pragma once
#include <iostream>
using namespace std;

template <class T>
class BSTNode
{
public:
    T key;
    BSTNode *parent;
    BSTNode *left;
    BSTNode *right;

    BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):key(value),parent(p),left(l),right(r)
    {

    }
};

template <class T>
class BSTree
{
private:
    BSTNode<T> *mRoot;

public:
    BSTree():mRoot(NULL){}
    ~BSTree(){}

    // 前序排序
    void preOrder()
    {
        preOrder(mRoot);
    }
    void inOrder()
    {
        inOrder(mRoot);
    }
    void postOrder()
    {
        postOrder(mRoot);
    }
    // 查找二叉樹中鍵值爲key的節點
    BSTNode<T>* SearchKey(const T key)
    {
        return SearchKey(mRoot, key);
    }
    BSTNode<T>* minKey()
    {
        return minKey(mRoot);
    }
    BSTNode<T>* maxKey()
    {
        return maxKey(mRoot);
    }
    // 插入節點
    void insert( T key)
    {
        BSTNode<T> *z = new BSTNode<T>(key, NULL, NULL, NULL);

        if (z == NULL)
        {
            return;
        }
        insert(mRoot, z);
    }

private:
    // 前序排序
    void preOrder(BSTNode<T> *tree) const
    {
        if (tree != NULL)
        {
            cout << tree->key << " ";
            preOrder(tree->left);
            preOrder(tree->right);
        }
    }

    // 中序排序
    void inOrder(BSTNode<T> *tree) const
    {
        if (tree != NULL)
        {
            preOrder(tree->left);
            cout << tree->key << " ";
            preOrder(tree->right);
        }
    }

    // 後序排序
    void postOrder(BSTNode<T> *tree) const
    {
        if (tree != NULL)
        {
            preOrder(tree->left);
            preOrder(tree->right);
            cout << tree->key << " ";
        }
    }
    BSTNode<T>* SearchKey(BSTNode<T>* pNode, const T key) const
    {
        // 遞歸查找
        /*if (pNode = NULL || key == pNode->key)
        {
            return pNode;
        }
        else if (key > pNode->key)
        {
            return SearchKey(pNode->right);
        }
        else
        {
            return SearchKey(pNode->left);
        }*/

        // 非遞歸查找
        BSTNode<T>* x = pNode;
        while (x != NULL)
        {
            if (key > x->key)
            {
                x = x->right;
            }
            else if (key < x->key)
            {
                x = x->left;
            }
            else
            {
                return x;
            }
        }

        return NULL;
    }
    // 將節點插入到二叉樹中
    void insert(BSTNode<T>* &tree, BSTNode<T> *Node)
    {
        BSTNode<T> *y = NULL;
        BSTNode<T> *x = tree;  
        while (NULL != x)
        {
            y = x;
            if (Node->key > x->key)
            {
                x = x->right;
            }
            else
            {
                x = x->left;
            }
        }

        Node->parent = y;       // 這到後面兩句爲關鍵代碼
        if (NULL == y)
        {
            tree = Node;
        }
        else if (Node->key > y->key)
        {
            y->right = Node;
        }
        else
        {
            y->left = Node;
        }
    }
    // 查找最小節點
    BSTNode<T>* minKey(BSTNode<T>* pNode) const 
    {
        while (pNode != NULL)
        {
            pNode = pNode->left;
        }

        return pNode;
    }
    BSTNode<T>* maxKey(BSTNode<T>* pNode) const
    {
        while (pNode != NULL)
        {
            pNode = pNode->right;
        }

        return pNode;
    }
    // 找節點(x)的後繼節點。即查找二叉樹中數值大於該節點的最小值
    BSTNode<T>* Successor(BSTNode<T>* x)
    {
        // 分三種狀況
        // 1. x有右孩子,找到以右孩子爲根的子樹的最小節點
        // 2. x沒有右孩子,當x爲左孩子,則x的父節點爲後繼節點
        // 2. x沒有右孩子,當x爲右孩子,則找x的最低父節點,而且該父節點具備左孩子
        if (x->right != NULL)
        {
            return minKey(x->right);
        }
        BSTNode<T>* y = x->parent;
        while ((NULL != y) &&(x == y->right))
        {
            x= y;
            y = y->parent;
        }

        return y;
    }
    // 找結點(x)的前驅結點。即查找"二叉樹中數據值小於該結點"的"最大結點"
    BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x)
    {
        // 若是x存在左孩子,則"x的前驅結點"爲 "以其左孩子爲根的子樹的最大結點"。
        if (x->left != NULL)
            return maxKey(x->left);

        // 若是x沒有左孩子。則x有如下兩種可能:
        // (01) x是"一個右孩子",則"x的前驅結點"爲 "它的父結點"。
        // (01) x是"一個左孩子",則查找"x的最低的父結點,而且該父結點要具備右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。
        BSTNode<T>* y = x->parent;
        while ((y!=NULL) && (x==y->left))
        {
            x = y;
            y = y->parent;
        }

        return y;
    }
                                        
    // 刪除二叉樹中的節點,並返回被刪除的節點
    //BSTNode<T>* RemoveNode(BSTNode<T>* &tree, BSTNode<T>* pNode)
    //{
    //    BSTNode<T>* x = tree;

    //    while (NULL != x && pNode->key != x->key)
    //    {
    //        if (pNode->key > x->key)
    //        {
    //            x = x->right;
    //        }
    //        else if (pNode->key < x->key)
    //        {
    //            x = x->left;
    //        }
    //    }

    //    // 找到或x爲空

    //}
};
View Code
相關文章
相關標籤/搜索