深度剖析八大排序算法
欢迎并且感谢大家指出我的问题,由于本人水平有限,有些内容写的不是很全面,只是把比较实用的东西给写下来,如果有写的不对的地方,还希望各路大牛多多指教!谢谢大家!🥰
在计算机科学领域,排序算法是基础且重要的算法类别,它能够将一组无序的数据按照特定的顺序(如升序或降序)重新排列。接下来,我们将详细探讨冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、堆排序和计数排序这八大排序算法。
冒泡排序
基本概念
冒泡排序是一种简单的比较排序算法,它通过多次比较相邻元素并交换位置,将最大(或最小)的元素逐步 “冒泡” 到数组的末尾。
核心思想
重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
算法步骤
- 比较相邻的元素。如果第一个比第二个大(升序),就交换它们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码实现(Java)
public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}
优缺点及适用场景
- 优点:实现简单,代码量少,比较稳定(相同元素的相对顺序在排序前后不会改变)。
- 缺点:时间复杂度较高,为 O (n²),在数据量较大时效率较低。
- 适用场景:适用于数据量较小且对稳定性有要求的场景。
选择排序
基本概念
选择排序是一种简单直观的排序算法,它在每一趟选择未排序序列中最小(或最大)的元素,存放到已排序序列的末尾。
核心思想
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
算法步骤
- 初始状态:无序区为整个数组,有序区为空。
- 第 1 趟排序:在无序区中选出最小(大)的元素,将它与无序区的第 1 个元素交换,此时有序区增加 1 个元素,无序区减少 1 个元素。
- 重复第 2 步,直到无序区为空。
代码实现(Java)
public class SelectionSort {public static void selectionSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {int minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}int temp = arr[minIndex];arr[minIndex] = arr[i];arr[i] = temp;}}
}
优缺点及适用场景
- 优点:简单直观,无论什么数据进去都是 O (n²) 的时间复杂度,所以如果数据规模较小,可以考虑使用。
- 缺点:时间复杂度高,同样为 O (n²),且不稳定。
- 适用场景:适用于数据量较小,对时间复杂度要求不高,且对稳定性没有要求的场景。
插入排序
基本概念
插入排序是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。
核心思想
把 n 个待排序的元素看成一个有序表和一个无序表。开始时有序表中只包含 1 个元素,无序表中包含 n - 1 个元素;排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复 n - 1 次可完成排序过程。
算法步骤
- 从第一个元素开始,该元素可以认为已经被排序。
- 取出下一个元素,在已经排序的元素序列中从后向前扫描。
- 如果已排序元素大于新元素,将已排序元素移到下一位置。
- 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置。
- 将新元素插入到该位置后。
- 重复步骤 2~5。
代码实现(Java)
public class InsertionSort {public static void insertionSort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}}
}
优缺点及适用场景
- 优点:在数据量较小或者部分有序的情况下,效率较高,并且是稳定的排序算法。
- 缺点:时间复杂度在最坏情况下为 O (n²),不适用于大规模数据排序。
- 适用场景:适用于数据量较小、部分有序的数据排序,以及对稳定性有要求的场景。
希尔排序
基本概念
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。它通过将原始数据分成多个子序列,对每个子序列进行插入排序,逐步减少增量,最终使整个序列有序。
核心思想
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 “基本有序” 时,再对全体记录进行依次直接插入排序。
算法步骤
- 选择一个增量序列 t1,t2,…,tk,其中 ti > tj, tk = 1。
- 按增量序列个数 k,对序列进行 k 趟排序。
- 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
代码实现(Java)
public class ShellSort {public static void shellSort(int[] arr) {int n = arr.length;for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}}
}
优缺点及适用场景
- 优点:希尔排序的时间复杂度比 O (n²) 要好很多,在中等规模数据下表现良好,并且实现相对简单。
- 缺点:希尔排序是不稳定的排序算法,并且其时间复杂度分析较为复杂。
- 适用场景:适用于中等规模数据的排序,对稳定性要求不高的场景。
快速排序
基本概念
快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组分为两部分,使得左边部分的元素都小于基准元素,右边部分的元素都大于基准元素,然后递归地对左右两部分进行排序。
核心思想
- 从数列中挑出一个基准值(通常选择第一个元素或最后一个元素)。
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区操作。
- 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
算法步骤
- 选择基准值 pivot。
- 初始化两个指针 left 和 right,left 指向数组的起始位置,right 指向数组的末尾位置。
- 从 right 开始,向左移动 right 指针,直到找到一个小于 pivot 的元素;从 left 开始,向右移动 left 指针,直到找到一个大于 pivot 的元素。
- 如果 left < right,交换这两个元素,然后继续步骤 3。
- 当 left >= right 时,将 pivot 与 left 指向的元素交换,此时 pivot 左边的元素都小于它,右边的元素都大于它。
- 递归地对 pivot 左边和右边的子数组进行快速排序。
代码实现(Java)
public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}
}
优缺点及适用场景
- 优点:平均时间复杂度为 O (nlogn),在大多数情况下表现非常高效,并且是一种原地排序算法(不需要额外的大量辅助空间)。
- 缺点:在最坏情况下(如数组已经有序),时间复杂度会退化为 O (n²),并且快速排序是不稳定的排序算法。
- 适用场景:适用于大规模数据的排序,对稳定性没有要求的场景。
归并排序
基本概念
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。它将一个数组分成两个子数组,对每个子数组进行排序,然后将排序好的子数组合并成一个最终的有序数组。
核心思想
- 把长度为 n 的输入序列分成两个长度为 n/2 的子序列。
- 对这两个子序列分别采用归并排序。
- 将两个排序好的子序列合并成一个最终的有序序列。
算法步骤
- 分解:将数组不断地分成两个子数组,直到子数组的长度为 1。
- 合并:将两个有序的子数组合并成一个更大的有序数组。合并时,比较两个子数组的元素,将较小的元素依次放入一个临时数组中,直到其中一个子数组的元素全部放入临时数组,然后将另一个子数组的剩余元素也放入临时数组。
- 将临时数组中的元素复制回原数组,完成一次合并。
- 重复步骤 2 和 3,直到所有子数组都合并成一个有序数组。
代码实现(Java)
public class MergeSort {public static void mergeSort(int[] arr) {int n = arr.length;if (n < 2) {return;}int mid = n / 2;int[] left = new int[mid];int[] right = new int[n - mid];System.arraycopy(arr, 0, left, 0, mid);System.arraycopy(arr, mid, right, 0, n - mid);mergeSort(left);mergeSort(right);merge(arr, left, right);}private static void merge(int[] arr, int[] left, int[] right) {int i = 0, j = 0, k = 0;while (i < left.length && j < right.length) {if (left[i] < right[j]) {arr[k] = left[i];i++;} else {arr[k] = right[j];j++;}k++;}while (i < left.length) {arr[k] = left[i];i++;k++;}while (j < right.length) {arr[k] = right[j];j++;k++;}}
}
优缺点及适用场景
- 优点:时间复杂度始终为 O (nlogn),并且是稳定的排序算法,适用于大规模数据的排序。
- 缺点:需要额外的空间来存储临时数组,空间复杂度为 O (n)。
- 适用场景:适用于对稳定性有要求,数据量较大的场景,如外部排序。
堆排序
基本概念
堆排序是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
核心思想
- 首先将待排序的数组构建成一个最大堆(升序排序时)或最小堆(降序排序时)。
- 然后将堆顶元素与堆的最后一个元素交换,此时堆的最后一个元素就是最大(或最小)的元素,将其从堆中移除(实际上是缩小堆的范围)。
- 对剩余的元素重新调整为最大堆(或最小堆),重复步骤 2,直到堆中只剩下一个元素,此时数组已经有序。
算法步骤
- 初始化堆:将数组构建成一个最大堆(或最小堆)。从最后一个非叶子节点开始,依次对每个非叶子节点进行向下调整操作,使其满足堆的性质。
- 交换与调整:将堆顶元素与堆的最后一个元素交换,然后对堆顶元素进行向下调整操作,使堆重新满足堆的性质。
- 重复步骤 2,直到堆中只剩下一个元素。
代码实现(Java)
public class HeapSort {public static void heapSort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 一个个取出元素for (int i = n - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 调整堆heapify(arr, i, 0);}}private static void heapify(int[] arr, int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest]) {largest = left;}if (right < n && arr[right] > arr[largest]) {largest = right;}if (largest!= i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 递归调整受影响的子树heapify(arr, n, largest);}}
}
优缺点及适用场景
- 优点:时间复杂度为 O (nlogn),并且是原地排序算法,不需要额外的大量辅助空间。
- 缺点:堆排序是不稳定的排序算法,并且实现相对复杂。
- 适用场景:适用于大规模数据的排序,对稳定性没有要求,并且空间有限的场景。
计数排序
基本概念
计数排序是一种非比较排序算法,它通过统计每个元素在数组中出现的次数,然后根据统计结果将元素按照顺序输出,从而实现排序。
核心思想
1.找出待排序数组中的最大值和最小值,确定计数数组的范围。
2.统计每个元素在数组中出现的次数,将统计结果存储在计数数组中。
3.根据计数数组,将每个元素按照出现的次数依次输出到结果数组中。
算法步骤
- 确定范围:遍历待排序数组,找出其中的最大值max和最小值min,计算出计数数组的长度countLength = max - min + 1。
- 初始化计数数组:创建一个长度为countLength的计数数组count,并将所有元素初始化为 0。
- 统计元素出现次数:再次遍历待排序数组,对于数组中的每个元素num,将count[num - min]的值加 1,表示该元素出现的次数。
- 计算前缀和:对计数数组进行处理,计算每个元素的前缀和。即从计数数组的第二个元素开始,每个元素都加上前一个元素的值。这一步的目的是让count[i]表示小于等于i + min的元素个数。
- 填充结果数组:创建一个与待排序数组长度相同的结果数组result。从待排序数组的末尾开始遍历,对于每个元素num,根据count[num - min]的值确定其在结果数组中的位置,然后将count[num - min]减 1。重复此步骤,直到所有元素都放入结果数组中。
代码实现
-
public class CountingSort {public static void countingSort(int[] arr) {if (arr == null || arr.length == 0) {return;}int max = arr[0];int min = arr[0];// 找出最大值和最小值for (int num : arr) {if (num > max) {max = num;}if (num < min) {min = num;}}int countLength = max - min + 1;int[] count = new int[countLength];// 统计每个元素出现的次数for (int num : arr) {count[num - min]++;}// 计算前缀和for (int i = 1; i < countLength; i++) {count[i] += count[i - 1];}int[] result = new int[arr.length];// 填充结果数组for (int i = arr.length - 1; i >= 0; i--) {result[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}// 将结果复制回原数组System.arraycopy(result, 0, arr, 0, arr.length);} }优缺点及适用场景
- 优点:时间复杂度为 O (n + k),其中 n 是待排序数组的长度,k 是数据的范围。在数据范围不大且数据量较大时,效率非常高。并且计数排序是稳定的排序算法。
- 缺点:对数据的要求比较苛刻,只能用于数据范围较小且数据为整数的情况。同时,需要额外的空间来存储计数数组,空间复杂度为 O (k) 。
- 适用场景:适用于数据范围有限,且对稳定性有要求的场景,比如对学生成绩(分数范围固定)进行排序等。
相关文章:
深度剖析八大排序算法
欢迎并且感谢大家指出我的问题,由于本人水平有限,有些内容写的不是很全面,只是把比较实用的东西给写下来,如果有写的不对的地方,还希望各路大牛多多指教!谢谢大家!🥰 在计算机科学领…...
python-leetcode-二叉树的层序遍历
102. 二叉树的层序遍历 - 力扣(LeetCode) # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right from coll…...
毕业设计:基于深度学习的高压线周边障碍物自动识别与监测系统
目录 前言 课题背景和意义 实现技术思路 一、算法理论基础 1.1 卷积神经网络 1.2 目标检测算法 1.3 注意力机制 二、 数据集 2.1 数据采集 2.2 数据标注 三、实验及结果分析 3.1 实验环境搭建 3.2 模型训练 3.2 结果分析 最后 前言 📅大四是整个大学…...
顺序表(ArrayList)
1、简介 顺序表是用一段物理地址连续 的存储单元依次存储数据元素的线性结构,一般情况下 采用数组存储 。在 数组 上完成数据的增删查改。( 顺序表的底层结构是一个数组 ) 2、顺序表的实现 下面是顺序表的一些基本成员和方法,能够…...
【Hadoop】Hadoop的HDFS
这里写目录标题 HDFS概述HDFS产出背景及定义HDFS产生背景HDFS定义 HDFS优缺点HDFS优点HDFS缺点 HDFS组成架构HDFS文件块大小 HDFS的Shell操作常用命令实操准备工作上传下载HDFS直接操作 HDFS的API操作客户端环境准备HDFS的API案例实操HDFS文件上传HDFS文件下载HDFS文件更名和移…...
C++ Primer 迭代器
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
使用 Postman 进行 API 测试:从入门到精通
使用 Postman 进行 API 测试:从入门到精通 使用 Postman 进行 API 测试:从入门到精通一、什么是 API 测试?二、Postman 简介三、环境搭建四、API 测试流程1. 收集 API 文档2. 发送基本请求示例:发送 GET 请求示例代码(…...
Leetcode面试高频题分类刷题总结
https://zhuanlan.zhihu.com/p/349940945 以下8个门类是面试中最常考的算法与数据结构知识点。 排序类(Sort): 基础知识:快速排序(Quick Sort), 归并排序(Merge Sort)的…...
8.原型模式(Prototype)
动机 在软件系统中,经常面临着某些结构复杂的对象的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。 之前的工厂方法和抽象工厂将抽象基类和具体的实现分开。原型模式也差不多&#…...
简单介绍一下什么是OpenFeign
OpenFeign是什么? OpenFeign是一个声明式的Http客户端,它可以用来发起Http请求 它主要用于SpringCloud微服务之间的通讯,让调用另一个服务的Java方法和调用本地方法一样快速和便捷 之前我们是用RestTemplate写一大堆东西发起Http请求远程调…...
力扣动态规划-20【算法学习day.114】
前言 ###我做这类文章一个重要的目的还是记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!! 习题 1.网格中的最小路径代价 题目链接…...
Codeforces Round 1002 (Div. 2)(部分题解)
补题链接 A. Milya and Two Arrays 思路:题意还是比较好理解,分析的话我加了一点猜的成分,对a,b数组的种类和相加小于4就不行,蒋老师的乘完后小于等于2也合理。 AC代码: #include <bits/stdc.h> u…...
在线销售数据集分析:基于Python的RFM数据分析方法实操训练
一、前言 个人练习,文章用于记录自己的学习练习过程,分享出来和大家一起学习。 数据集:在线销售数据集 分析方法:RFM分析方法 二、过程 1.1 库的导入与一些必要的初始设置 import pandas as pd import datetime import matplo…...
小程序设计和开发:要如何明确目标和探索用户需求?
一、明确小程序的目标 确定业务目标 首先,需要明确小程序所服务的业务领域和目标。例如,是一个电商小程序,旨在促进商品销售;还是一个服务预约小程序,方便用户预订各类服务。明确业务目标有助于确定小程序的核心功能和…...
【C语言深入探索】:指针高级应用与极致技巧(二)
目录 一、指针与数组 1.1. 数组指针 1.2. 指向多维数组的指针 1.2.1. 指向多维数组元素的指针 1.2.2. 指向多维数组行的指针 1.3. 动态分配多维数组 1.4. 小结 二、指针与字符串 2.1. 字符串表示 2.2. 字符串处理函数 2.3. 代码示例 2.4. 注意事项 三、指针与文件…...
2.策略模式(Strategy)
定义 定义一系列算法,把它们一个个封装起来,并且使他们可互相替换(变化)。该模式使算法可独立于使用它的客户程序(稳定)而变化(拓展,子类化)。 动机(Motiva…...
手写MVVM框架-构建虚拟dom树
MVVM的核心之一就是虚拟dom树,我们这一章节就先构建一个虚拟dom树 首先我们需要创建一个VNode的类 // 当前类的位置是src/vnode/index.js export default class VNode{constructor(tag, // 标签名称(英文大写)ele, // 对应真实节点children,…...
【Blazor学习笔记】.NET Blazor学习笔记
我是大标题 我学习Blazor的顺序是基于Blazor University,然后实际内容不完全基于它,因为它的例子还是基于.NET Core 3.1做的,距离现在很遥远了。 截至本文撰写的时间,2025年,最新的.NET是.NET9了都,可能1…...
C++11中的bind
官方文档对于bind接口的概述解释:Bind function arguments 在C11中,std::bind 是一个非常有用的工具,用于将函数、成员函数或函数对象与特定的参数绑定在一起,生成一个新的可调用对象。std::bind 可以用于部分应用函数参数、改变…...
llama.cpp的C语言API使用
我们知道,一般运行大语言模型都是在Python上运行的,可是Python的性能太差了,不适合用于生产环境,因此可以采用llama.cpp提供的API在C语言上运行大模型。 llama.cpp的下载 Windows下的下载 我们需要下载llama.cpp的两个部分&…...
鼠标拖尾特效
文章目录 鼠标拖尾特效一、引言二、实现原理1、监听鼠标移动事件2、生成拖尾元素3、控制元素生命周期 三、代码实现四、使用示例五、总结 鼠标拖尾特效 一、引言 鼠标拖尾特效是一种非常酷炫的前端交互效果,能够为网页增添独特的视觉体验。它通常通过JavaScript和C…...
基于 docker 的mysql 5.7 主备集群搭建
创建挂载目录和配置文件 主节点 mkdir -p /mysql_master/mysql/log mkdir -p /mysql_master/mysql/data mkdir -p /mysql_master/mysql/conf vim /mysql_master/mysql/conf/my.cnf[mysqld] datadir/var/lib/mysql #MySQL 数据库文件存放路径 server_id 1 #指定数据库服务器的…...
金山打字游戏2010绿色版,Win7-11可用DxWnd完美运行
金山打字游戏2010绿色版,Win7-11可用DxWnd完美运行 链接:https://pan.xunlei.com/s/VOIAYCzmkbDfdASGJa_uLjquA1?pwd67vw# 进入游戏后,如果输入不了英文字母(很可能是中文输入状态),就按一下“Shift”键…...
爬虫学习笔记之Robots协议相关整理
定义 Robots协议也称作爬虫协议、机器人协议,全名为网络爬虫排除标准,用来告诉爬虫和搜索引擎哪些页面可以爬取、哪些不可以。它通常是一个叫做robots.txt的文本文件,一般放在网站的根目录下。 robots.txt文件的样例 对有所爬虫均生效&#…...
(10) 如何获取 linux 系统上的 TCP 、 UDP 套接字的收发缓存的默认大小,以及代码范例
(1) 先介绍下后面的代码里要用到的基础函数: 以及: (2) 接着给出现代版的 读写 socket 参数的系统函数 : 以及: (3) 给出 一言的 范例代码,获取…...
【玩转 Postman 接口测试与开发2_016】第13章:在 Postman 中实现契约测试(Contract Testing)与 API 接口验证(上)
《API Testing and Development with Postman》最新第二版封面 文章目录 第十三章 契约测试与 API 接口验证1 契约测试的概念2 契约测试的工作原理3 契约测试的分类4 DeepSeek 给出的契约测试相关背景5 契约测试在 Postman 中的创建方法6 API 实例的基本用法7 API 实例的类型实…...
25.02.04 《CLR via C#》 笔记14
第二十一章 托管堆和垃圾回收 内存分配过程 CLR维护一个“下一次分配指针”(NextObjPtr),指向当前托管堆中第一个可用的内存地址 计算类型所需的字节数,加上对象开销(类型对象指针、同步块索引)所需字节数…...
day8-面向对象
目录 面向对象1、面向对象介绍2、类和对象类和对象类的几个补充注意事项 3、封装 面向对象 1、面向对象介绍 ⭐️面向对象介绍: 面向:拿、找对象:能干活的东西面向对象编程:拿东西过来做对应的事情 面向对象编程的例子&#x…...
Pyside6 的QObject 类
PySide6 中的 QObject 是 Qt 框架的核心基类,所有需要信号与槽、事件处理、内存管理的对象均需要继承自它。以下是关于 QObject 的详细说明,从功能、关键特性到实际代码示例进行阐述: 1. 核心功能 QObject 提供了以下基本能力: …...
【Java】位图 布隆过滤器
位图 初识位图 位图, 实际上就是将二进制位作为哈希表的一个个哈希桶的数据结构, 由于二进制位只能表示 0 和 1, 因此通常用于表示数据是否存在. 如下图所示, 这个位图就用于标识 0 ~ 14 中有什么数字存在 可以看到, 我们这里相当于是把下标作为了 key-value 的一员. 但是这…...
