二叉查找树C++实现

二分查找树特点:(1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;(2)任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)任意节点的左、右子树

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

全栈程序员社区此处内容已经被作者隐藏,请输入验证码查看内容
验证码:
请关注本站微信公众号,回复“验证码”,获取验证码。在微信里搜索“全栈程序员社区”或者“www_javaforall_cn”或者微信扫描右侧二维码都可以关注本站微信公众号。

二分查找树特点:

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

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

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

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

前序遍历:中左右

中序遍历:左中右

序遍历:左右中

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

二叉查找树C++实现
二叉查找树C++实现

#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

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120253.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • wireshark分析无线wifi包

    wireshark分析无线wifi包1、找到station或者ap的mac地址,使用过滤命令找到两者的网络包交互mac地址过滤:wlancontains00:11:22:33:44:55报文类型过滤:wlan.fc.type_subtype==0x0输入wlan.会列出很多可用无线过滤命令参考:https://blog.csdn.net/neal_hddnwpu/article/details/82586235…

    2022年7月21日
    31
  • C++编程语言中重载运算符(operator)介绍「建议收藏」

    C++编程语言中重载运算符(operator)介绍「建议收藏」本文主要介绍在C++编程语言中使用关键字operator重载运算符(也称“重载操作符”)的相关知识,同时通过示例代码介绍使用关键字operator重载运算符的具体方法。1概述1.1Whatoperator是C++的一个关键字,它和运算符(如=)一起使用,表示一个运算符重载函数,在理解时可将operator和待重载的运算符整体(如operator=)视为一个函数名。使用operator重载运算符,是C++扩展运算符功能的方法。使用operator扩展运

    2022年6月1日
    73
  • [深度学习] FM & FFM 算法基本原理

    [深度学习] FM & FFM 算法基本原理在推荐系统和计算广告业务中,点击率CTR(click-throughrate)和转化率CVR(conversionrate)是衡量流量转化的两个关键指标。准确的估计CTR、CVR对于提高流量的价值,增加广告及电商收入有重要的指导作用。无论使用什么类型的模型,点击率这个命题可以被归纳到二元分类的问题,我们通过单个个体的特征,计算出对于某个内容,是否点击了,点击了就是1,没点击就是0。对于任何二元分类的问题,最后我们都可以归结到逻辑回归上面。早期的人工特征工程+LR(Logisti…

    2022年5月1日
    68
  • jar包反编译工具

    jar包反编译工具在学习和开发JAVA项目中,我们经常会用到第三方提供的一些jar。使用这些第三方工具包,可以提高我们开发的效率,缩短开发的时间。有的第三方工具,提供具体的使用说明和源代码,有时有的却不提供源代码,使用说明也不是很具体,这对我们使用就非常不方便。  有道是,知其然才知其所以然。有时候,我们…

    2022年7月8日
    29
  • Mac 读写NTFS硬盘

    Mac 读写NTFS硬盘查看磁盘DeviceNode:【diskutilinfo磁盘路径】diskutilinfo/Volumes/CPBA_X64FRE_ZH-CN_DV5通过DeviceNode卸载磁盘:【sudoumount/dev/disk2s1】…

    2022年6月18日
    25
  • solidworks怎样绘制螺纹_螺纹孔怎么画

    solidworks怎样绘制螺纹_螺纹孔怎么画1随便画一个圆柱2在原来的地方画一个一摸一样的圆(草图2)3在特征选项卡中点击曲线-螺旋线/涡状线4设置螺距和圈数,画螺旋线5建立一个基准面,第一参考是点,第二参考是曲线6在刚才

    2022年8月4日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号