数据结构--二叉查找树 Binary Search Tree

文章目录

    • 1.二叉查找树概念
    • 2.二叉查找树操作
      • 2.1 查找
      • 2.2 插入
      • 2.3 删除
      • 2.4 其他
    • 3. 支持重复数据的二叉查找树
    • 4 有散列表了,还需要二叉查找树?
    • 5 代码实现

1.二叉查找树概念

二叉查找树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。
在这里插入图片描述

2.二叉查找树操作

2.1 查找

在这里插入图片描述

2.2 插入

在这里插入图片描述

2.3 删除

在这里插入图片描述

2.4 其他

  • 支持快速地查找最大节点和最小节点、前驱节点和后继节点。
  • 中序遍历二又查找树,可以输出有序的数据序列,时间复杂度是 O(n) ,非常高效。因此,二叉查找树也叫作二叉排序树。

3. 支持重复数据的二叉查找树

  • 通过链表和支持动态扩容的数组等数据结构,把值相同的数据都存储在同一个节点上。
  • 每个节点仍然只存储一个数据。在查找插入位置的过程中,如果碰到一个节点的值,与要插入数据的值相同,我们就将这个要插入的数据放到这个节点的右子树,也就是说,把这个新插入的数据当作大于这个节点的值来处理。

在这里插入图片描述

  • 在二叉查找树中,查找、插入、删除等很多操作的时间复杂度都跟树的高度成正比。两个极端情况的时间复杂度分别是 O(n) 和 O(logn) ,分别对应二叉树退化成链表的情况和完全二叉树。
  • 为了避免时间复杂度的退化,针对二又查找树,我们又设计了一种更加复杂的树,平衡二叉查找树,时间复杂度可以做到稳定的 O(logn)

4 有散列表了,还需要二叉查找树?

  • 散列表时间复杂度可以做到常量级的O(1), 而二叉查找树在比较平衡的情况下, 时间复杂度才是 O(logn), 相对散列表,好像并没有什么优势,那我们为什么还要用二叉查找树呢?
    几个原因:
  • 第一, 散列表中的数据是无序存储的, 如果要输出有序的数据,需要先进行排序.而对于二叉查找树来说,我们只需要中序遍历,就可以在O(n)的时间复杂度内,输出有序的数据序列.
  • 第二, 散列表扩容耗时很多,而且当遇到散列冲突时,性能不稳定,尽管二叉查找树的性能不稳定,但是在工程中,我们最常用的平衡二叉查找树的性能非常稳定,时间复杂度稳定在O(logn).
  • 第三, 尽管散列表的查找等操作的时间复杂度是常量级的,但因为哈希冲突的存在,这个常量不一定比 logn 小,所以实际的查找速度可能不一定比 O(logn) 快. 加上哈希函数的耗时,也不一定就比平衡二又查找树的效率高.
  • 第四, 散列表的构造比二又查找树要复杂,需要考虑的东西很多. 比如散列函数的设计、冲突解决办法、扩容、缩容等.平衡二又查找树只需要考虑平衡性这一个问题,而且这个问题的解决方案比较成熟、固定.
  • 最后,为了避免过多的散列冲突,散列表装载因子不能太大,特别是基于开放寻址法解决冲突的散列表,不然会浪费一定的存储空间.
  • 综合这几点, 平衡二又查找树在某些方面还是优于散列表的, 所以,这两者的存在并不冲突. 我们在实际的开发过程中,需要结合具体的需求来选择使用哪一个.

5 代码实现

/*** @description: 二叉查找树* @author: michael ming* @date: 2019/5/16 23:48* @modified by: */
#include <iostream>
#include <random>
#include <time.h>
using namespace std;
template <class T>
class BSTNode
{
public:T data;BSTNode<T> *left, *right;BSTNode():left(NULL), right(NULL){}BSTNode(const T& d, BSTNode<T> *l = NULL, BSTNode<T> *r = NULL){data = d;   left = l;   right = r;}
};
template <class T>
class BST
{
private:BSTNode<T>* root;int nodeLen;
public:BST():root(NULL){}~BST(){clear(root);root = NULL;}void clear(BSTNode<T>* nodeP){if(nodeP == NULL)return;if (nodeP == NULL)return;clear(nodeP->left);clear(nodeP->right);delete nodeP;}BSTNode<T>* get_root() const {  return root;    }bool isEmpty() const {  return root == NULL;    }T* search(const T& d) const{return search(d, root);}T* search(const T& d, BSTNode<T>* p) const{while(p != NULL){if(d == p->data)return &(p->data);else if(d < p->data)p = p->left;elsep = p->right;}return 0;}T* get_max_data(){if(root == NULL)return NULL;BSTNode<T>* temp = root;while(temp->right != NULL)temp = temp->right;return &temp->data;}T* get_min_data(){if(root == NULL)return NULL;BSTNode<T>* temp = root;while(temp->left != NULL)temp = temp->left;return &temp->data;}void insert(const T& d){BSTNode<T> *p = root, *prev = NULL;while(p != NULL){prev = p;if(d < p->data)p = p->left;elsep = p->right;}if(root == NULL)root = new BSTNode<T>(d);else if(d < prev->data)prev->left = new BSTNode<T>(d);elseprev->right = new BSTNode<T>(d);}void del(T d){if(root == NULL)return;BSTNode<T> *p = root, *pfather = NULL;while(p != NULL && p->data != d){pfather = p;if(d > p->data)p = p->right;elsep = p->left;}if(p == NULL)   //没找到dreturn;if(p->left != NULL && p->right != NULL)//要删除的节点有2个子节点{BSTNode<T> *minP = p->right, *minPFather = p;//找到右子树最小的跟要删的交换while(minP->left != NULL)   //右子树最小的肯定在左节点{minPFather = minP;minP = minP->left;}p->data = minP->data;   //把右子树最小的数付给要删除的节点datap = minP;   //minP付给p,删除ppfather = minPFather;}//要删除的是叶节点或者只有1个节点BSTNode<T>* child;if(p->left != NULL)child = p->left;else if(p->right != NULL)child = p->right;elsechild = NULL;if(pfather == NULL)//p是根节点root = child;else if(p == pfather->left)pfather->left = child;elsepfather->right = child;delete p;p = NULL;}int get_height(BSTNode<T>* nodep)  //递归法, 求左右子树高度,较大的+1{if(nodep == NULL)return 0;int leftheight = get_height(nodep->left);int rightheight = get_height(nodep->right);return max(leftheight, rightheight) + 1;}void inOrderPrint(BSTNode<T>* nodep)    //二叉查找树用中序打印,是有序的{if (nodep == NULL)return;inOrderPrint(nodep->left);cout << nodep->data << " ";inOrderPrint(nodep->right);}
};int main()
{BST<int> intBST;srand(time(0));for(int i = 0; i < 6; ++i){intBST.insert(rand());}intBST.insert(7);if(intBST.search(7))cout << *(intBST.search(7)) << endl;cout << "BST height: " << intBST.get_height(intBST.get_root()) << endl;intBST.inOrderPrint(intBST.get_root());cout << "max : " << *(intBST.get_max_data()) << ", min : " << *(intBST.get_min_data()) << endl;intBST.del(7);intBST.inOrderPrint(intBST.get_root());return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新蚂蚁金服Java面试题:Docker+秒杀设计+RocketMQ+亿级数据设计

蚂蚁金服一面&#xff1a; 1 自我介绍 2 讲一下ArrayList和linkedlist的区别&#xff0c;ArrayList的扩容方式&#xff0c;扩容时机。 3 hashmap的实现&#xff0c;以及hashmap扩容底层实现。 4 NIO了解么&#xff0c;讲一下和BIO的区别&#xff0c;AIO呢。阻塞&#xff0c;…

论文浅尝 | 常识用于回答生成式多跳问题

链接&#xff1a;https://arxiv.org/pdf/1809.06309.pdfAnsweringTasks多跳问题一般需要模型可以推理、聚合、同步上下文中不同的信息。就需要理解那些人类通过背景知识可以理解的限制关系。本文提出了一个很强的baseline模型&#xff08;multi-attention pointer-generator d…

中国智能投顾行业

原文地址&#xff1a; 中国智能投顾行业 一、概要 财富管理与新兴金融科技的结合&#xff0c;使得财富管理行业正在进入新的阶段——智能财富管理。近几年全球出现的智能投顾模式已然成为智能财富管理的一大热点。智能投顾&#xff0c;简而言之&#xff0c;就是基于投资者的投…

别让数据坑了你!用置信学习找出错误标注(附开源实现)

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | JayLou娄杰&#xff08;NLP算法工程师&#xff0c;信息抽取方向&#xff09;编 | 北大小才女小轶美 | Sonata1 前言在实际工作中&#xff0c;你是否遇到过这样一个问题或痛点&#xff1a;无论是通过哪种…

助力句子变换:35W抽象、43W同义、13W简称三大知识库对外开源

句子变换&#xff0c;是指根据给定中文句子&#xff0c;借助某种语言处理手段&#xff0c;扩展出一定数据规模的中文句子集合&#xff0c;是一个从1到N的过程&#xff0c;目的在于解决搜索&#xff08;查询扩展&#xff09;、分类&#xff08;样本扩充&#xff09;、抽取&#…

数据结构--红黑树 Red Black Tree

文章目录1.概念2.操作2.1 左旋、右旋&#xff08;围绕某个节点的左/右旋&#xff09;2.2 插入2.3 删除3. 代码1.概念 二叉树在频繁动态增删后&#xff0c;可能退化成链表&#xff0c;时间复杂度由 O(lgn) 变成 O(n)。&#xff08;不平衡&#xff09;平衡二叉树&#xff0c;树中…

深度学习在用户画像标签模型中的应用

原文地址&#xff1a;https://blog.csdn.net/chaishen10000/article/details/79324016 最近一段时间都在学习深度学习&#xff0c;想着在用户画像标签模型中看能不能用上&#xff0c;终于&#xff0c;用了一个多月的时间&#xff0c;结合实际的场景和数据&#xff0c;搭建了一套…

最强京东Java面试题(共现场4面)

一面&#xff08;基础面&#xff1a;约1个小时&#xff09; 自我介绍&#xff0c;主要讲讲做了什么和擅长什么 springmvc和spring-boot区别 Autowired的实现原理 Bean的默认作用范围是什么&#xff1f;其他的作用范围&#xff1f; 索引是什么概念有什么作用&#xff1f;MyS…

工业界求解NER问题的12条黄金法则

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | JayLou娄杰&#xff0c;夕小瑶编 | 可盐可甜兔子酱美 | Sonata众所周知&#xff0c;命名实体识别&#xff08;Named Entity Recognition&#xff0c;NER&#xff09;是一项基础而又重要的NLP词法分析任…

POJ 1577 Falling Leaves(二叉查找树)

题目链接&#xff1a;http://poj.org/problem?id1577 题目大意&#xff1a; 二叉查找树按照叶子节点&#xff0c;从下往上抹去该树&#xff0c;给出抹除字符序列&#xff0c;求该二叉树&#xff0c;并前序打印 解题思路&#xff1a; 最后抹除的是根节点&#xff0c;把抹除的…

最新阿里内推高级Java面试题

阿里Java一面题目 osi七层网络模型&#xff0c;五层网络模型&#xff0c;每次层分别有哪些协议 死锁产生的条件&#xff0c; 以及如何避免死锁&#xff0c;银行家算法&#xff0c;产生死锁后如何解决 如何判断链表有环 虚拟机类加载机制&#xff0c;双亲委派模型&…

智能投顾-用户画像、投资组合选择、推荐引擎、大数据挖掘

智能投顾面面观之AI慕课 原文地址&#xff1a;https://www.jianshu.com/p/437c895794e0?utm_campaignharuki&utm_contentnote&utm_mediumreader_share&utm_sourceweixin “最后编辑于 2017.11.14 21:49”>2017.11.13 11:47* 自我介绍 大家好&#xff0c;我是…

论文浅尝 | KG Embedding with Iterative Guidance from Soft Rules

论文链接&#xff1a;https://www.aaai.org/ocs/index.php/AAAI/AAAI18/paper/download/16369/16011发表会议&#xff1a;AAAI 2018摘要知识图谱表示学习旨在将实体和关系嵌入到向量空间&#xff0c;同时保留知识图谱的内在结构。传统方法主要基于关系三元组学习知识图谱的嵌入…

人工智能轨道交通行业周刊-第69期(2023.12.11-12.24)

本期关键词&#xff1a;集装箱智能管理、智慧工地、智能应急机器人、车辆构造、大模型推理 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨…

可信知识实证在UGC时代情报应用中的思考与探索

可信知识实证在UGC时代情报应用中的思考与探索 在当前互联网高度发达、可发布信息源和信息渠道猛增且多元化的大背景下&#xff0c;信息形态变得广泛且多模。从传统的纸质文档&#xff0c;到中期的电子结构化文档、电子非结构化文本&#xff0c;再到如今的语音信息、图片信息、…

Google | 创造Youtube单次上线最高收益!解决推荐中的信息茧房困境

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 江城编 | 夕小瑶今天分享一下Google在WSDM 2019的一篇将强化学习应用于Youtube推荐的论文&#xff0c;作者宣称是获得了Youtube近两年来单次上线的最高收益。文章仔细介绍了RL在Youtube上的实践方案细节…

POJ 2785 有多少种4个数相加等于0的方案(二分查找 or hash)

文章目录1.二分查找法1.1 思路&#xff1a;1.2 AC代码2.hash查找法2.1 思路&#xff1a;2.2 Wrong Answer 代码2.3 Time Limit Exceeded 代码2.4 偷懒失败&#xff0c;hash_map在poj中不存在2.5 哈希表二叉查找树&#xff08;超时&#xff09;2.6 AC代码&#xff08;哈希数组法…

2018最新阿里Java技术三面(已拿Offer):JVM+高并发性能+单点登录+微服务

一面 1.自我介绍 2.谈一个你觉得你学到最多的项目&#xff0c;使用了什么技术&#xff0c;挑战在哪里 3.Spring的bean的作用域&#xff1f;&#xff08;比如&#xff1a;singleton&#xff0c;prototype等&#xff09; 4.Spring的IOC实现原理&#xff1f;没有无参构造函数能…

论文浅尝 | 基于局内去噪和迁移学习的关系抽取

动机在远程监督任务中&#xff0c;除了语料的错误标注问题&#xff0c;还存在句内噪声单词过多的问题&#xff0c;即多数句子都存在一些与表达关系无关的词汇&#xff0c;这个问题未有人关注。当前研究的另一个问题是&#xff0c;句子特征抽取器采用随机初始化的方法&#xff0…

关于知识图谱,我们接下来该研究什么?斯坦福教授们给出了答案

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 舒意恒&#xff08;南京大学硕士生&#xff0c;知识图谱方向&#xff09;编 | 北大小才女小轶本文整理了斯坦福大学 CS 520 知识图谱研讨会课程的第 10 集的内容&#xff0c;主要是关于知识图谱未来的研…