zoukankan      html  css  js  c++  java
  • 二叉查找树C++实现

    二分查找树特点:

    (1) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

    (2) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

    (3) 任意节点的左、右子树也分别为二叉查找树。

    (4) 没有键值相等的节点(no duplicate nodes)。

    前序遍历:中左右

    中序遍历:左中右

    序遍历:左右中

    二叉查找树的重点在于如何找节点的前驱节点和后继节点

    #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
  • 相关阅读:
    Celery框架
    Tensorflow安装记录
    OpenFace的一些了解
    CentOS+Uwsgi+Nginx发布Flask开发的WebAPI
    Always On 集群监听创建失败问题
    SQL Server 安装好后 Always On群组配置
    Sql server 2016 Always On 搭建Windows集群配置
    汕头市队赛 SRM13 T3
    bzoj 1314: River过河 树套树+单调队列
    hdu 6119 …&&百度之星 T6
  • 原文地址:https://www.cnblogs.com/xiaobingqianrui/p/6533556.html
Copyright © 2011-2022 走看看