二叉查找树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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vim —- 自己主动的按钮indent该命令「建议收藏」

    vim —- 自己主动的按钮indent该命令

    2022年1月17日
  • JAVA设计模式初探之装饰者模式

    这个模式花费了挺长时间,开始有点难理解,其实就是定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。…

    2022年3月11日
  • QQ空间缓存图片_QQ空间原图

    QQ空间缓存图片_QQ空间原图不知各位遇到特别长的图片时是怎么处理的?是截取符合长宽的部分做临时展示?还是硬要长宽100%模糊(啥也看不清)展示?还是先拿一个压缩的图片做占位,在鼠标移入或点击时放大预览?今天偶然打开PC端QQ空间时,我发现了一种似乎更好的方式——鼠标移入时在范围内上下滚动图片预览,移出时停止滚动。直到用户点击图片跳转到详情展示:分析这种方式着实让我“眼前一亮”,一定程度上带给了用户新奇的体验感。顺着思路,一键f12打开源码,我看到了这样的代码:显而易见,QQ应该是采用了js监听鼠标位

    2022年8月10日
  • PyCharm设置护眼背景色

    PyCharm设置护眼背景色.方法一:      File->Seting->Editor-Colors->General->Text->Defaulttext->BackGround设置为E1F4E4

    2022年8月25日
  • Java实现MD5加密的方式

    Java实现MD5加密的方式  MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。那么它到底有什么,又什么好处呢,会被这么广泛的运用在应用开发中。  1、什么是MD5  MD5加密全程是Message-DigestAlgoorithm5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字符串。  例如我们要加密一篇文章,那么我们会随机从每段话或者每行中获取…

    2022年7月27日
  • java interface 里面的抽象方法默认public[通俗易懂]

    java interface 里面的抽象方法默认public[通俗易懂]①interface里声明的方法,会自动在方法名之前加上publicabstract②interface里声明的field,会自动在field之前加上publicstaticfinal这是因为,interface存在的目的就是要和外界公开如要在别的类里,实现interface里面的,抽象方法。这个方法的修饰符,也一定要public.也就是说,不能用比public还要受限制的修饰符。…

    2022年10月7日

发表回复

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

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