数据结构与算法回顾-3:二叉查找树

近几年预训练语音大模型汇总 语音大模型研究近年来取得显著进展,主要包括wav2vec 2.0(2020)、HuBERT(2021)、WavLM(2022)、Data2Vec(2022)、Whisper(2023)等代表性工作。这些模型采用自监督学习框架,通过掩码预测、对比学习等策略在大规模语音数据上预训练,可有效应用于语音识别、情感分析、疾病检测等下游任务。其中wav2vec 2.0首次将对比学习引入语音领域,Whisper通过68万小时弱监督数据实现强大的跨语言能力。这些突破为低资源语音任务提供了通用特征提取方案,推动了医疗语音分析 阅读详情

1、概念

二叉查找树(BST) 是一种二叉树,它的每个结点都只有左右两个链接,分别指向自己的左子结点和右子结点,并且每个结点都大于其左子树中的任意结点的键,并且小于任意右子树的任意结点的键。(注意和堆的区别)

2、代码实现

2.1 使用循环的方式来进行查找和插入

下面的代码中使用了循环的方式来将指定的键值对插入到表中。缺点:相比于使用递归的方式这里的代码显得比较冗长,而且在循环之中没办法统计和更新加入新的分支之后它的各个父结点的分支统计N的数量信息:

	public class BST<Key extends Comparable<Key>, Value> {
	    private Node<Key, Value> root;
	    private int size;
	
        // 二叉查找树的结点的定义
	    private static class Node<Key extends Comparable<Key>, Value> {
	        Node<Key, Value> leftChild;
	        Key key;
	        Value value;
	        Node<Key, Value> rightChild;
	        int N; // 每个结点的子结点的总数
	
	        Node(Node<Key, Value> leftChild, Key key, Value value, int N, Node<Key, Value> rightChild) {
	            this.leftChild = leftChild;
	            this.key = key;
	            this.value = value;
	            this.rightChild = rightChild;
	            this.N = N;
	        }
	    }
	
	    public int size() {
	        return size(root);
	    }
	
	    private int size(Node<Key, Value> node) {
	        if (node == null) return 0;
	        else return node.N;
	    }
	
	    public void put(Key key, Value value) {
	        if (key == null) throw new IllegalArgumentException("Key cannot be null.");
	        Node<Key, Value> newNode = new Node<Key, Value>(null, key, value, 1, null);
	        if (root == null) {
	            root = newNode;
	        } else {
	            Node<Key, Value> node = root;
	            while (true) {
	                int cmp = key.compareTo(node.key);
	                if (cmp > 0) {
	                    if (node.rightChild == null) {
	                        node.rightChild = newNode;
	                        size++;
	                        break;
	                    } else {
	                        node = node.rightChild;
	                    }
	                } else if (cmp < 0) {
	                    if (node.leftChild == null) {
	                        node.leftChild = newNode;
	                        size++;
	                        break;
	                    } else {
	                        node = node.leftChild;
	                    }
	                } else {
	                    node.value = value;
	                    break;
	                }
	            }
	        }
	    }
	
	    public Value get(Key key) {
	        if (isEmpty() || key == null) {
	            return null;
	        }
	        Node<Key, Value> node = root;
	        while (true) {
	            int cmp = key.compareTo(node.key);
	            if (cmp > 0) {
	                if (node.rightChild == null) {
	                    return null;
	                } else {
	                    node = node.rightChild;
	                }
	            } else if (cmp < 0) {
	                if (node.leftChild == null) {
	                    return null;
	                } else {
	                    node = node.leftChild;
	                }
	            } else {
	                return node.value;
	            }
	        }
	    }
	
	    public boolean isEmpty() {
	        return size == 0;
	    }
	}

2.2 使用递归的方式进行查找和插入

如上所述,上面的代码使用了循环的方式来实现二叉树,下面使用递归的方式来实现二叉树的查找和插入:

    public void put(Key key, Value value) {
        root = put(root, key, value);
    }

    // 下面这段递归的代码并不难理解:每次根据比较的结果,
    // 如果比当前结点大,就到右子树中继续递归查找
    // 如果比当前结点小,就到左子树中继续递归查找
    private Node<Key, Value> put(Node<Key, Value> node, Key key, Value value) {
        if (node == null) { // 递归终止的条件,注意返回的对象的意义
            return new Node<Key, Value>(null, key, value, 1, null);
        }
        int cmp = key.compareTo(node.key);
        if (cmp < 0) {
            node.leftChild = put(node.leftChild, key, value);
        } else if (cmp > 0) {
            node.rightChild = put(node.rightChild, key, value);
        } else {
            node.value = value;
        }
        node.N = size(node.leftChild) + size(node.rightChild) + 1;
        return node;
    }

    public Value get(Key key) {
        return get(root, key);
    }

    // 也是使用递归的方式来进行查找操作
    private Value get(Node<Key, Value> node, Key key) {
        if (node == null) {
            return null;
        }
        int cmp = key.compareTo(node.key);
        if (cmp < 0) {
            return get(node.leftChild, key);
        } else if (cmp > 0) {
            return get(node.rightChild, key);
        } else {
            return node.value;
        }
    }

可以看出,递归可以在添加完各个结点之后返回的时候将结点的统计信息加入到 N 字段上。这个在上面的基于循环的方式实现的二叉树中是没有实现的。

2.3 性能

  1. 二叉树的性能与二叉树的形状有一定的关系,考虑一种极端的情况,如果每次插入的数据相互之间是一种递增的关系,那么得到的二叉树就应该是一个链表的形状。这种情形下的二叉树的查找和插入的效率是最低的,而当二叉查找树是完全平衡的时候,查找的效率是最高的。
  2. 由N个随机键构成的二叉查找树中,查找命中平均需要的比较次数为 2lnN(约1.39lgN).
  3. 由N个随机键构成的二叉查找树中,插入操作和查找未命中平均需要的比较次数为 2lnN(约1.39lgN).

2.4 二叉树的其他方法实现

虽然,上面我们已经实现了二叉树的基本的插入和查找的操作,但是在实际的二叉树应用中,我们还需要提供一些其他的方法来方便使用。

2.4.1 最大键和最小键

根据二叉树的性质,我们可以知道,不断地对二叉树的左子结点进行查找,即可得到键最小的结点。同理,不断对二叉树的有子结点进行查找,即可得到最大的结点。下面是使用循环来实现的获取最小和最大结点的值的方法:

    public Value getMax() {
        Node<Key, Value> node = root;
        while (node != null) {
            if (node.rightChild == null) {
                return node.value;
            }
            node = node.rightChild;
        }
        return null;
    }

    public Value getMin() {
        Node<Key, Value> node = root;
        while (node != null) {
            if (node.leftChild == null) {
                return node.value;
            }
            node = node.leftChild;
        }
        return null;
    }
2.4.2 排名

所谓的排名就是返回二叉树的某个结点在所有结点中的编号,这里我们使用 rank(Key) 方法来获取某个键对应的排名,使用 select(int) 来获取某个排名对应的键。

如果是根结点,那么我们直接返回它的左子树的结点的数量即可;如果要查找的键在左子树中,我们返回该键在左子树中的排名;如果要查找的键在右子树中,我们要返回根节点加上它在右子树中的排名。

    public int rank(Key key) {
        return rank(root, key);
    }

    private int rank(Node<Key, Value> node, Key key) {
        if (node == null) {
            return 0;
        }
        int cmp = key.compareTo(node.key);
        if (cmp > 0) { // 使用递归的方式,不断加上各根结点的左子树+根的数量,加上它自己在左子树中的排名
            return 1 + size(node.leftChild) + rank(node.rightChild, key);
        } else if (cmp < 0) {
            return rank(node.leftChild, key);
        } else {
            return size(node.leftChild);
        }
    }

    public Key select(int index) {
        Node<Key, Value> node = select(root, index);
        if (node == null) {
            return null;
        }
        return node.key;
    }

    private Node select(Node<Key, Value> node, int index) {
        if (node == null) {
            return null;
        }
        // 根据当前结点的左右两个子树的结点的大小与索引的比较的结果
        // 来决定要向左子树继续查找,还是向右子树继续查找
        int size = size(node.leftChild);
        if (size > index) {
            return select(node.leftChild, index);
        } else if (size < index) {
            return select(node.rightChild, index - size - 1);
        } else {
            return node;
        }
    }
3.4.3 删除最大键和最小键

对于删除最小键,不断深入到左子树中,直到遇到一个左子树为空的结点,将其删除即可;对于删除最大键,不断深入右子树,直到遇到一个右子树为空的结点,将其删除即可。

下面是使用 Java 实现的删除最大键和最小键的实现,这里除了删除最大和最小的键之外,还加入了统计结点数量的相关的逻辑。

    public void delMax() {
        root = delMax(root);
    }

    private Node<Key, Value> delMax(Node<Key, Value> node) {
        if (node.rightChild == null) {
            return node.leftChild;
        }
        node.rightChild = delMax(node.rightChild); // 当当前结点的右侧结点为空,就将当前结点的左子结点作为右结点
        node.N = size(node.leftChild) + size(node.rightChild) + 1;
        return node;
    }

	public void delMin() {
        root = delMin(root);
    }

    private Node<Key, Value> delMin(Node<Key, Value> node) {
        if (node.leftChild == null) {
            return node.rightChild;
        }
        node.leftChild = delMin(node.leftChild); // 左结点的左子节点为空时返回左结点的右结点作为自己的左结点
        node.N = size(node.leftChild) + size(node.rightChild) + 1;
        return node;
    }
3.3.4 删除操作

删除某个节点的时候需要分成几种情况来处理:

  1. 当某个被删的结点两个子结点只存在一个的时候,直接将被删结点的子树连接连接到被删结点处即可;
  2. 当某个被删的结点两个子结点都不存在的时候,直接将其删除即可;
  3. 当某个被删的结点两个子结点都存在的时候,我们可以将被删结点的右子树称为T。如下图所示,我们需要找到T中最小的结点,即图中的绿色的结点。因为它最小,所以它有个比较好的特性——左子树为空。就像下图,我们只要将该绿色的结点从T中移动到被删的位置。如果该绿色结点有右子树,我们可以将子树连接到N原来的位置。

下面是使用 Java 实现的一份从树中删除某个键的结点的代码:

    public void delete(Key key) {
        root = delete(root, key);
    }

    private Node<Key, Value> delete(Node<Key, Value> node, Key key) {
        if (node == null) {
            return null;
        }
        int cmp = key.compareTo(node.key);
        if (cmp > 0) { // 比当前的结点大,到右子树中继续查找并删除
            node.rightChild = delete(node.rightChild, key);
        } else if (cmp < 0) { // 比当前结点小,到左子树中继续查找并删除
            node.leftChild = delete(node.leftChild, key);
        } else { // 与当前结点相等
            // 如果左子结点或者右子结点为空的话,直接将另一个子树连接到被删除的位置即可
            if (node.leftChild == null) {
                return node.rightChild;
            }
            if (node.rightChild == null) {
                return node.leftChild;
            }
            // 当被删的结点左右子结点都存在时的情况
            Node<Key, Value> temp = node;
            node = min(temp.rightChild);
            node.rightChild = delMin(temp.rightChild);
            node.leftChild = temp.leftChild;
        }
        node.N = size(node.leftChild) + size(node.rightChild) + 1;
        return node;
    }

如果删除的结点中有子树的时候这里的处理方式是,先获取树中最小的结 点N,然后删除 T 中最小的结点并将根据结点赋值为 N 的右结点,删除的过程中实际上已经将 N 原来的右子树的结点放在了 N 原来的位置,然后将被删结点的左子树赋值给 N 即可。

3.4.5 范围查找

获取二叉树的所有子结点的键的时候,我们可以使用背包来实现:

    public Iterable<Key> keys(Key lo, Key hi) {
        Bag<Key> keys = new Bag<Key>();
        addKey(root, keys, lo, hi);
        return keys;
    }

    private void addKey(Node<Key, Value> node, Bag<Key> bag, Key lo, Key hi) {
        if (node == null) {
            return;
        }
        int cmplo = lo.compareTo(node.key); // <=0
        int cmphi = hi.compareTo(node.key); // >=0
        if (cmphi >= 0 && cmplo <= 0) {
            bag.add(node.key);
        }
        addKey(node.leftChild, bag, lo, hi);
        addKey(node.rightChild, bag, lo, hi);
    }
张力控制速度闭环控制算法 这个算法的核心思想是通过比较实际速度和期望速度的差异来调整控制信号,以达到稳定的速度控制。比例项用于直接根据误差调整输出,积分项用于积累误差并进行补偿,微分项用于预测误差的变化趋势并进行调整。张力控制是在许多工程和工业应用中非常重要的一个过程,它涉及到通过调节力的大小来实现稳定的工作状态。通过合理设置比例、积分和微分系数,并结合实际系统的特性进行调试和优化,可以实现准确稳定的张力控制。速度闭环控制算法通过比较实际速度和期望速度之间的差异,并根据差异调整系统的输出,以保持速度稳定。 阅读详情

相关推荐

Eplan2022 复制已有的宏文件生成新的原理图宏文件

Eplan2022 新建原理图宏文件

haier123888的博客 1万+

[Java]-二叉查找树

二叉查找树 定义: 一棵二叉查找树(BST)是一棵二叉树,其中每个结点都含有一个Comparable的键(以及相关联的值),且每个结点的键都大于其左子树任意节点的键而小于右子树任意节点的键。 一棵二叉查找树代表了一组键(及其对应值)的集合,而同一个集合可以用多棵不同的二叉查找树表示 如上图,当我们将一棵二叉查找树的所有键投影到一条直线上,保证一...

renboyu010214的博客 293

FPGA赋能:从加权灰度均值到快速收敛的自动曝光实战

本文深入探讨了FPGA在工业视觉自动曝光算法中的应用,重点介绍了加权灰度均值法的优化实现与快速收敛策略。通过硬件友好的算法改造和流水线架构设计,FPGA方案能在1帧内完成曝光调整,显著提升处理速度和能效比,适用于复杂光照条件下的工业检测场景。

weixin_29306317的博客 82

java最优有序查找——红黑树(RBT)算法

在大量数据中常用的查找数据的做法有四类:顺序查找,二分查找,二叉树查找(BST),红黑树查找(RBT)。 这四类查找方法分别对应着四种基本思想原理: 顺序查找 —— 无序简单查找 二分查找 —— 有序查找,每次折半搜索,插入数据费时 二叉树查找(BST) —— 不平衡二叉树有序查找,插入与搜索综合性能较优 红黑树查找(RBT) —— 平衡二叉树有序查找,插入与搜索

往事散云烟,十寸光阴换一钱 4433

oracle p6 破解版下载,Primavera P6项目管理软件 16~17 图文详细安装教程(附下载)

Primavera P6 Professional项目管理软件结合了Oracle和Microsoft SQL Server关系数据库,是一款非常好用且功能强大的综合的项目管理软件(PPM) 解决方案,主要用于土建等方面的施工计划分析,具有进度时间安排与资源控制功能的多用户、多项目系统,支持多层项目分层结构、角色与技能导向的资源安排、记录实际数据、自定义视图以及自定义数据,本文主要为大家图文详细介绍...

weixin_33978451的博客 4907

计组实验4 控制冒险与分支预测

目录前言实验内容背景知识分支预测技术⭐阻塞周期计算方法不开启 BTB开启 BTBpart 1 矩阵乘法与优化未开启 BTB 的分析开启 BTB 的分析part 2 设计代码使 BTB 无效part 3 循环展开优化矩阵乘法未开启 BTB开启 BTB结束语结论 前言 上一篇博客:计组实验3 mips冒险之流水线冒险 摸了半个月了。。。咕咕咕 今天来写计组实验 4 这个实验非常简单,就是有点难。 这个实验比较容易算错,或者是被模拟器出人意料的结果搞的神神叨叨的,所以今天来记录并且详细分析该实验。 注:请务必阅

AKGWSB 's blog 5666

【数据结构】筛选法建堆

如果已经存在N个数据元素,如何将这些元素按照堆的要求存储在一个一维数组中呢?这就是堆的建立问题。 首先我们可以想到按照之前的堆的插入算法将这N个元素依次插入一个空堆中,分析时间复杂度,每插入一个元素最多要进行logN(即堆的深度)次比较,所以对于N个元素用插入法建堆的时间复杂度是O(NlogN)。 这里要介绍的是筛选法建堆,它可以在线性时间复杂度下完成建堆。以最大堆为例介绍具体操作过程: 首先将

萧十一的技术小站 5万+

Lumerical FDTD新手必看:从零开始搭建光子晶体仿真环境(附完整脚本)

本文为Lumerical FDTD新手提供光子晶体仿真环境的完整搭建指南,涵盖从基础参数设置到脚本编写的全流程。通过典型光子晶体带隙分析案例,详细讲解结构建模、仿真参数配置及后处理技巧,并附赠完整MATLAB脚本,帮助用户快速掌握FDTD仿真核心技术。

3c4x5z6v7b的博客 1050

数据结构-排序: 选择排序(堆选择排序法)

1.堆排序定义      n个关键字序列Kl,K2,…,Kn称为堆,当且仅当该序列满足如下性质(简称为堆性质):      (1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤ )      若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子...

weixin_33725515的博客 392

跨越移植陷阱:ESP-IDF下LVGL与ILI9341的组件化集成与常见避坑指南

本文详细解析了在ESP-IDF环境下将LVGL图形库与ILI9341显示屏驱动进行组件化集成的完整流程。重点介绍了移植过程中的关键配置策略、内存管理优化技巧以及常见问题解决方案,帮助开发者有效规避内存溢出、显示异常等典型陷阱,实现高效稳定的嵌入式GUI开发。

yhn456789的博客 622

UniApp 覆盖安装后首次进入 APP pages.json 不生效的解决方案

通过以上步骤,解决了缓存问题导致的首次加载异常。此方案的关键在于强制更新文件名,从根本上避免旧缓存的干扰。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 681

堆排序——BuildHeap和Heapify函数的实现

堆排序——BuildHeap和Heapify函数的实现 堆排序——BuildHeap和Heapify函数的实现(4) BuildHeap和Heapify函数的实现 因为构造初始堆必须使用到调整堆的操作,先讨论Heapify的实现。 ① Heapify函数思想方法 每...

847

什么是 AIDV(AI 定义汽车):从软件定义到智能决策的范式革命

AI定义汽车(AIDV),是指以人工智能(尤其是大模型、深度学习、强化学习)为核心引擎,以车载AI芯片为算力底座,以“数据闭环”为迭代支撑,重构汽车感知、决策、执行全链路,实现“感知智能化、决策自主化、体验个性化、迭代自动化”的新一代智能汽车发展范式。其核心是让汽车从“执行工具”升级为“具备自主学习与智能决策能力的移动智能终端”,核心价值是“车与人的深度协同”与“复杂场景的自主适配”。

getusushu的博客 95

数据结构快速教程3—查找

本文包括查找内容的完全总结。查找分为三种结构,其中顺序查找、折半查找、索引、二叉查找(排序)树是必须要掌握的内容。本文提供了封装的模块化代码。

2302_79476384的博客 1070

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数据结构快速回顾——二叉查找树

二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 任意节点的左、右子树也分别为二叉查找树。 ...

weixin_30527143的博客 75

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

数据结构回顾与巩固

前言 本文将探讨三问题:一、数据结构是如何应运而生:二、常见的数据结构与相应的算法有哪些:三、数据结构的发展: 1.数据结构是如何应运而生 “数据结构”作为一门独立的课程在国外是从1968年才开始设立的。 1968年美国唐纳德·克努特(Donald Ervin Knuth)教授开创了数据结构的最初体系,所著的《计算机程序设计艺术》第一卷《基本算法》是第一本较系统地阐述数...

baidu_33512336的博客 337

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

数据结构与算法回顾-4:平衡查找树

二叉树虽然能解决查找的问题,但是在某些情况下,比如当任意相邻的两个元素之间是按照升序或者降序插入的话,那么得到的树将是一个链表的形状。当然这只是一种极端的情况,只是用来说明,树的形状对二叉查找的效率有很大的影响。 这里的平衡二叉树能够让树保持完美的平衡,不会出现极端的成为链表等,而且我们也会试图去保持树的完美平衡。 它实现这个平衡目的的方式是:对于 3-结点,如果再向其插入数据,就会使其变成 4-...

你好,开发者 405

算法回顾

为什么80%的码农都做不了架构师?>>> ...

weixin_33704591的博客 290

20172324 2018-2019-1《程序设计与数据结构》课程总结

20172324 2018-2019-1《程序设计与数据结构》课程总结 每周作业链接汇总 20172324 2018-2019-1 《程序设计与数据结构》第一周学习总结:软件质量、数据结构、算法分析 20172324 2018-2019-1 《程序设计与数据结构》第二周学习总结:集合概述——栈、,利用栈计算后缀表达式、链式结构——栈、无链接的元素和双向列表 20172324 2018-...

362

【Java从头开始到光头结束】No7.回顾Map集合基础与树形数据结构

Map集合基础与树形数据结构1.Map集合基础2.简述树形数据结构 基础回顾 → Map集合基础与树形数据结构 ———————————————————————————————————— 文章部分内容选自书本《码出高效:Java开发手册》 1.Map集合基础 之前的博客中已经对List集合中的ArrayList及LinkedList有过源码的大致分析和学习拓展,今天这篇博文主要是Map集合的一个铺垫(因为是回顾,所以不会有很基础的概念),之后我们会对Map集合中的常用实现类进行源码分析和学习。附上之前博客

菲林都已拆走 616

数据结构与算法笔记3

本笔记记录王争专栏数据结构与算法之美的学习记录,以便自己复习回顾,代码部分均已经过验证,可直接使用 文章目录1. 二分查找(Binary Search)二分查找应用场景的局限性二分查找的应用场景2. 4种变形1. 查找第一个值等于给定值的元素2. 查找最后一个值等于给定值的元素3. 查找第一个大于等于给定值的元素4. 查找最后一个小于等于给定值的元素3. 解答问题4. 散列表1. 散列的思想2...

wjl31802的博客 692

数据结构与算法笔记4

本笔记记录王争专栏数据结构与算法之美的学习记录,以便自己复习回顾,代码部分均已经过验证,可直接使用 文章目录1. 二叉树基础1. 树2. 二叉树 Binary Tree3. 如何存储一个二叉树4. 二叉树的遍历代码实现2. 二叉查找树 Binary Search Tree1. 概念2. 操作1. 查找操作2. 插入操作3. 删除操作4. 其他操作3. 支持重复数据的二叉查找树4. 二叉查找树的...

wjl31802的博客 536

python数据结构与算法分析 pdf_绝了!数据结构与算法分析,一线架构师仅用一份PDF搞定(赠送)...

很多开发者都知道“程序=数据结构+算法”这个著名的公式,并不真正明白算法的定义或概念。究竟什么是算法呢?从字面意义上理解,算法即用于计算的方法,通过这种方法可以达到预期的计算结果。实际上,数据结构与算法分析也是一个大学问,关于这一方面,我不得不感叹,一线架构师的水准是超出我们常人的想象,简直绝了!仅用一份PDF文档就能够搞定,说得非常清楚。当然,这份「数据结构与算法分析」的文档资料,是可以免费分享...

weixin_39790717的博客 3163

C 关于二叉查找树的回顾,并简述结构接口设计

前言   最经想改写C用的配置读取接口, 准备采用hash或二叉树提到原先用的链表,提高查找效率.就回顾一下二叉树,这里分享一下二叉查找树,代码很精简的, 适合学习运用二叉树查找. 需要基础 1.具备C基础知识 2.知道数据结构,最好知道一点二叉树结构 能够学到 1.稳固二叉查找树 2.C良好编码格式习惯 3.tree数据结构几种流行套路(设计) 参照 1.二叉查找树...

weixin_30469895的博客 124

数据结构与算法(有了如此高效的散列表,为啥还需要二叉树呢?)

回顾:上一节我们讲了二叉树的基本知识,今天我们讲一个更加高效的二叉查找树,他支持动态的插入,删除操作            我们之前说过,散列表也是可以支持高效的动态的插入,删除操作,而且时间复杂度是O(1),为何右如此高效的散列表,还需要二叉查找树呢?带着这个问题,我们来学习一下二叉查找树       二叉查找树:顾名思义就是为了快速的查找而诞生的,不仅这样,他还支持高效的动态插入,删除操作...

w5201314ws6123的博客 536

android基础回顾(算法)

Q:怎么理解数据结构? 技术点:数据结构 思路:数据结构的定义、分类 参考回答:研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。 按照逻辑结构分类 线性结构:线性表、栈、队列 非线性结构:树、图 按照存储结构分为顺序结构、链式结构、索引结构、哈希结构 Q:什么是斐波那契数列...

qq_35874340的博客 417
上一篇: 数据结构与算法回顾-2:排序算法小结
下一篇: 数据结构与算法回顾-4:平衡查找树
开发者如是说
博客等级 码龄10年 67粉丝 163原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值