数据结构学习笔记——排序
排序
1. 排序相关概念
稳定性:关键字相同的数据记录,排序后相对顺序仍保持不变
例如,两个25,在排序完后,有*的25仍在后方,说明该排序算法是稳定的
内部排序:数据元素全部放在内存中的排序
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序
2. 常见排序算法及实现
2.1 插入排序
直接插入排序
直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列
简单来说,待排序数据如下
排序轮次如下
每一轮排好一个数,下一轮新拿出来的数,插入到原来已排好的序列中,直到所有数都排好
直插特性总结:
- 元素集合越接近有序,算法的时间效率越高
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 算法稳定
代码示例:
// 插入排序
void InsertSort(int* a, int n) {for (int i = 1; i < n; i++) {int temp = a[i];int j = i;while (j > 0){if (a[j - 1] > temp) {a[j] = a[j - 1];}else { break; }j--;}a[j] = temp;}
}
希尔排序(缩小增量排序)
希尔排序法的基本思想是:先选定一个整数gap,把待排序文件中所有记录分成gap个组,所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后,gap取更小的值(一般是gap/2),重复上述分组和排序的工作。当到达gap=1时,所有记录在统一组内排好序。
可以这么理解:
- 预排序,使数组接近有序
- 执行插入排序
看如下例子
待排序序列
取gap的值,一般是n/2,所以这里取3
排序后结果如第二行所示
一般来说gap /= 2后为1,但这里先取gap = 2以便理解
然后最后一趟gap = 1
希尔特性总结:
- 希尔排序是对直接插入排序的优化
- 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果
- 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些书中给出的希尔排序的时间复杂度都不固定
- 稳定性:不稳定
代码示例:
// 希尔排序
// 注意,如果每组各自排的话,会有四重循环(最外层gap变化,第二层不同组各自处理,最后两层为插入自带)
// 此处仅3层循环,使多组排序同时进行
void ShellSort(int* a, int n) {int gap = n / 2;while (gap){for (int i = gap; i < n; i++) {int temp = a[i];int j = i;while (j >= gap){if (a[j - gap] > temp) {a[j] = a[j - gap];}else { break; }j -= gap;}a[j] = temp;}gap /= 2;}
}
2.2 选择排序
选择排序
基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完
看一下示例就好理解了
初始序列
选择特性总结:
- 直接选择效率一般,实际中很少使用
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:不稳定
示例代码
// 选择排序
// 此为优化过的选择,每一轮分别找到一个最大值和最小值,放于开头和末尾
void SelectSort(int* a, int n) {int bg = 0, ed = n - 1;while (bg < ed){int min_idx = bg, max_idx = ed;for (int i = bg; i <= ed; i++) {if (a[i] > a[max_idx]) {max_idx = i;}if (a[i] < a[min_idx]) {min_idx = i;}}int temp = a[bg];a[bg] = a[min_idx];a[min_idx] = temp;temp = a[ed];// 如果发生如下情况,此时bg的值经过交换已经到了min_idx中,需要调整max_idx的值if (bg == max_idx){ max_idx = min_idx; }a[ed] = a[max_idx];a[max_idx] = temp;bg++, ed--;}
}
堆排序
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆
// 初始序列:21,25,49, 25*,16,08
那么初始集合如下
调整为最大堆(或根据需求调整为最小堆)
排序过程
堆排序特性总结:
- 使用堆来选数,效率高很多
- 时间复杂度:O(N*logN)
- 空间复杂度:O(1)
- 稳定性:不稳定
示例代码
// 堆排序
void AdjustDwon(int* a, int n, int root) {int parent = root;int child = parent * 2 + 1;while (child < n) {if (child + 1 < n && a[child + 1] > a[child]) {++child;}if (a[child] > a[parent]) {int temp = a[child];a[child] = a[parent];a[parent] = temp;parent = child;child = parent * 2 + 1;}else { break; }}
}
void HeapSort(int* a, int n) {for (int i = n / 2 - 1; i >= 0; i--) {AdjustDwon(a, n, i);}for (int i = n - 1; i >= 0; i--) {int temp = a[0];a[0] = a[i];a[i] = temp;AdjustDwon(a, i, 0);}
}
2.3 交换排序
冒泡排序
根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,逐个向后走(或者向前),把较大的放后面(或者放前面)
冒泡特性总结:
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:稳定
示例代码
// 冒泡排序
void BubbleSort(int* a, int n) {for (int i = 0; i < n; i++) {for (int j = 0; j < n - i - 1; j++) {if (a[j] > a[j + 1]) {int temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;}}}
}
快速排序(很重要!!!)
快排在面试中经常可能会让你手撕,而且变化也不少!务必熟悉熟悉再熟悉
1. 快排基本知识
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止
// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int array[], int left, int right)
{if(right - left <= 1)return;// 按照基准值对array数组的 [left, right)区间中的元素进行划分int div = partion(array, left, right);// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)// 递归排[left, div)QuickSort(array, left, div);// 递归排[div+1, right)QuickSort(array, div+1, right);
}
上述为快速排序递归实现的主框架,与二叉树前序遍历规则非常像,在写递归框架时可想想二叉树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可
将区间按照基准值划分为左右两半部分的常见方式有:
-
hoare版本
示例代码:
// 快速排序hoare版本 int PartSort1(int* a, int left, int right) {int key = left;while (right - left > 1){while (right - left > 1 && a[right - 1] >= a[key]) { right--; }while (right - left > 1 && a[left] <= a[key]) { left++; }int temp = a[left];a[left] = a[right - 1];a[right - 1] = temp;}int temp = a[key];a[key] = a[left];a[left] = temp;return left; }
霍尔版本效率不差,但是容易引发几个疑问:
- 为什么能保证相遇时的值一定比基准值小呢?
- 为什么要先让右边出发,再让左边出发呢?
- 如果右边或者左边一直到遇到另一方都没找到合适的值怎么办?
这些疑问经过推演是可以解决的,但这使得霍尔版本有了一定的理解门槛,于是就有了如下的挖坑法
-
挖坑法
挖坑法的效率和霍尔版本是一样的,但相对来说更容易理解
示例代码
// 快速排序挖坑法 int PartSort2(int* a, int left, int right) {int key = a[left], flag = 1;while (right - left > 1){if (flag) {if (a[right - 1] >= key) { right--; }else {a[left] = a[right - 1];flag = 0;}}else {if (a[left] <= key) { left++; }else {a[right - 1] = a[left];flag = 1;}}}a[left] = key;return left; }
-
前后指针版
这是与前两者不太一样的方法,还蛮新颖的,学校都没教
示例代码
// 快速排序前后指针法 int PartSort3(int* a, int left, int right) {int pre = left, cur = left + 1, key = left;while (cur < right){if (a[cur] < a[key]) {pre++;int temp = a[pre];a[pre] = a[cur];a[cur] = temp;}cur++;}int temp = a[key];a[key] = a[pre];a[pre] = temp;return pre; }
2. 快排优化
快排相对来说效率还是不错的,因为在理想状态下,每次找到的基准值都恰好是中位数,分开来的左右序列长度是差不多的,看起来就和二叉树一样,如此效率就几乎能和堆排序媲美
但是,一旦遇到不理想的情况,效率就差很多了
试想,如果每次取到的基准值都是最小/最大的,那么下一组的序列长度和原来相比只小了一个单位,那么参考上图,树的高度可以达到n,复杂度将变为O(n^2)
更重要的是,作为递归调用的函数,对空间的消耗是很高的,而快排通常运用的场景绝对都是大体量的数据,这样一来,就很容易发生诸如栈溢出的情况,这是我们所不希望看到的
那么想要优化快排,以下是比较常见的方法
-
三数取中法选key
我们当然希望避免选到的key过大或者过小,毕竟这样总会使效率有所下降,其中之一的办法,就是取3个数,第一个,最后一个,以及中间一个,取这三个数的中间值作为key值,至少能某种程度上减小上述情况发生的概率
当然为了较少地改动之前已写过的代码,选到的key值可以和第一个值做个交换,然后再执行之前的代码即可
-
递归到小的子区间时,可以考虑使用插入排序
在数据量较小时,再使用快排,和其他排序算法(比如插入排序)相比,就没什么优势了,使用非递归的其他算法可以减少一些栈帧的开销
-
使用非递归方法
单独列一个,看下方
3. 非递归实现快排
我们知道,函数调用时所需要的空间是由栈分配的(至少在大多数编程语言中如此)在递归的函数中,每递归一次,就会多创建一个栈帧,占用栈的一部分空间
那么我们可以考虑用数据结构——栈(注意这和上面的栈不是同一个概念!!!)来模拟实现递归的调用过程,比方说在栈中存放每组的开头和结尾,直到栈空之前循环执行,这同样能完成任务,但好处在于:
- 不会再过多的创建栈帧,降低栈溢出的风险(这里指的是调用栈或执行栈,与数据结构的栈不同!)
- 使用的数据结构——栈,占用的空间是动态申请的,而动态申请的空间是由堆分配的,不会占用栈的空间
- 堆的空间是比栈的空间大得多的,所以总体来说,空间调用的安全性更高了
参考代码如下
// 快速排序 非递归实现
void QuickSortNonR(int* a, int left, int right) {stack<int>stk;stk.push(left);stk.push(right);while (!stk.empty()){right = stk.top();stk.pop();left = stk.top();stk.pop();if (right - left <= 1) { continue; }int temp = PartSort1(a, left, right);stk.push(left);stk.push(temp);stk.push(temp + 1);stk.push(right);}
}
当然既然想到了用数据结构的栈来实现非递归,就不可避免的想到能不能用队列
这当然是可以的,不过,不同组的执行顺序会有所不同,我们可以看下对比图
-
用栈实现非递归
-
用队列实现非递归
之前说过,快速排序递归实现的主框架,与二叉树前序遍历规则非常像,用栈实现的非递归也是如此,而相应的,用队列实现非递归则和层序遍历很相似,事实上,我们实现层序遍历就是利用了队列
再广义一点的说,其实树的前中后序遍历,其实都是深度优先遍历,而层序遍历,则是广度优先遍历
可以尝试下树的前中后序能否用非递归来写
快排特性总结:
- 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
- 时间复杂度:O(N*logN)
- 空间复杂度:O(logN)
- 稳定性:不稳定
2.4 归并排序
基本思想:
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
核心步骤
归并排序相应的,类似树的后序遍历
参考代码
// 归并排序递归实现
void _MergeSort(int* a, int* temp, int bg, int ed) {if (bg == ed) { return; }int mid = (bg + ed) / 2;_MergeSort(a, temp, bg, mid);_MergeSort(a, temp, mid + 1, ed);int i = bg;int bg1 = bg, ed1 = mid, bg2 = mid + 1, ed2 = ed;while (bg1 <= ed1 && bg2 <= ed2){if (a[bg1] < a[bg2]) {temp[i++] = a[bg1++];}else {temp[i++] = a[bg2++];}}while (bg1 <= ed1){temp[i++] = a[bg1++];}while (bg2 <= ed2){temp[i++] = a[bg2++];}for (int j = bg; j <= ed; j++) {a[j] = temp[j];}
}
void MergeSort(int* a, int n) {int* temp = new int[n];_MergeSort(a, temp, 0, n - 1);delete[]temp;temp = NULL;
}
非递归实现归并
根据之前非递归实现快排的经验,我们可能会先想到使用栈,但实际上,由于归并和后序的相似性,对栈的空间占用就会很高(尝试自己推演看)实际上,使用循环迭代的方式也可以实现
使用一个迭代变量gap,表示两组归并的长度,每一轮gap*2
在每一轮中,从左往右循环归并不同组
需要注意一下的就是越界问题
示例代码
void MergeSortNonR(int* a, int n) {int* temp = new int[n];int gap = 1;while (gap < n){for (int i = 0; i < n; i += 2 * gap) {int bg1 = i, ed1 = i + gap - 1;int bg2 = i + gap, ed2 = i + 2 * gap - 1;if (bg2 >= n) { break; }if (ed2 >= n) { ed2 = n - 1; }int j = i;while (bg1 <= ed1 && bg2 <= ed2){if (a[bg1] < a[bg2]) {temp[j++] = a[bg1++];}else {temp[j++] = a[bg2++];}}while (bg1 <= ed1){temp[j++] = a[bg1++];}while (bg2 <= ed2){temp[j++] = a[bg2++];}for (int k = i; k <= ed2; k++) {a[k] = temp[k];}}gap *= 2;}delete[]temp;temp = NULL;
}
归并排序特性总结
- 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题(既可以做内排序,也可以做外排序)
- 时间复杂度:O(N*logN)
- 空间复杂度:O(N)
- 稳定性:稳定
2.5 非比较排序
常见的非比较排序有:基数排序、计数排序、桶排序,其中计数排序比较有实践意义,这里先介绍计数排序
思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。
操作步骤:
- 统计相同元素出现次数
- 根据统计的结果将序列回收到原来的序列中
计数排序特性总结
- 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限(一般是整数)
- 时间复杂度:O(MAX(N,范围))
- 空间复杂度:O(范围)
- 稳定性:稳定
基数排序和桶排序,看如下介绍
基数排序
基数排序是一种线性时间复杂度的排序算法,它通过依次对每一位进行排序来处理整数或字符串。这个“位”可以是指数字中的个位、十位、百位等,或者是字符串中的字符位置。基数排序通常使用计数排序或桶排序作为子程序来对每一位进行排序。它可以按照从最低有效位到最高有效位或者从最高有效位到最低有效位的方式进行排序。
优点:对于固定长度的关键字序列,基数排序可以在 O(nk) 时间内完成排序,其中 n 是关键字的数量,k 是关键字的最大长度。
缺点:基数排序依赖于数据类型,适用于整数或字符串等离散且有固定长度的数据结构。
桶排序
桶排序是将数组分到有限数量的桶里,每个桶再单独排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序)。桶排序假设输入是由一个随机过程生成的,并且均匀分布在区间 [0, 1) 上。当输入数据能够均匀分配到各个桶中时,桶排序的效果最佳。
优点:如果输入数据能均匀地分布到各个桶中,那么桶排序的时间复杂度可以达到 O(n + k),这里 n 是元素数量,k 是桶的数量。
缺点:桶排序的性能很大程度上取决于输入数据的分布情况。如果数据不是均匀分布的,某些桶可能会包含过多的元素,导致效率降低。
相关文章:
数据结构学习笔记——排序
排序 1. 排序相关概念 稳定性:关键字相同的数据记录,排序后相对顺序仍保持不变 例如,两个25,在排序完后,有*的25仍在后方,说明该排序算法是稳定的 内部排序:数据元素全部放在内存中的排序 外…...
CSS 样式 margin:0 auto; 详细解读
一、基本语法 margin 属性是用于设置元素的外边距,它可以接受一个、两个、三个或四个值。 margin:0 auto 是一种简洁的写法,其中包含了两个值。 二、值的含义 第一个值 0 表示元素的上下外边距为 0。这意味着该元素的顶部和底部与相邻元素或父元素之间…...
leetcode24-两两交换链表中的节点
leetcode 24 思路 本题仍然引入虚拟头节点来实现会更加简单,因为不用单独考虑对于头节点进行交换的场景对于边界条件考虑更少,交换的步骤按照下图中的步骤来 首先将dummy->22->11->3 但是在第一步的时候,dummy->2,…...
项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(六)
文章目录 一、考试管理模块实现1、添加考试功能实现1.1 页面设计1.2 前端功能实现1.3 后端功能实现1.4 效果展示2、考试管理功能实现2.1 页面设计2.2 前端功能实现2.3 后端功能实现2.3.1 后端查询接口实现2.3.2 后端编辑接口实现2.3.3 后端删除接口实现2.4 效果展示二、代码下载…...
flutter的web页面
有几个服务器 有几个后台 直接通过web端进去虽然说很方便,但… 于是把web页面镶嵌到应用里面去, 这样就换了个方式打开web页面了 比如这里有有个列表 这里是写死了,活的列表可以通过io去获取 import package:flutter/material.dart; imp…...
YOLOv10改进,YOLOv10检测头融合RFAConv卷积,添加小目标检测层(四头检测)+CA注意机制,全网首发
摘要 空间注意力已广泛应用于提升卷积神经网络(CNN)的性能,但它存在一定的局限性。作者提出了一个新的视角,认为空间注意力机制本质上解决了卷积核参数共享的问题。然而,空间注意力生成的注意力图信息对于大尺寸卷积核来说是不足够的。因此,提出了一种新型的注意力机制—…...
使用vue-next-admin框架后台修改动态路由
vue-next-admin框架是一个基于 Vue 3 和 Vite 构建的后台管理系统框架。它采用了最新的前端技术栈,旨在提供一个高效、灵活、现代化的管理后台解决方案。该框架主要用于构建功能丰富且易于定制的管理后台应用,适合各种中大型项目。 其主要特点包括&am…...
Windows蓝牙驱动开发-经典蓝牙音频
本文介绍 Windows 中的蓝牙经典音频功能。 蓝牙经典音频支持通过高级音频分发配置文件(A2DP)和单声道播放和通过免手配置文件(HFP)进行立体声音频播放。 Windows 支持各种音频编解码器和采样率,具体取决于 Windows 版本、耳机的功能以及音频设备的播放或捕获功能的当…...
力扣动态规划-3【算法学习day.97】
前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?建议灵神的题单和代码随想录)和记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关…...
如何将本地电脑上的文件夹设置为和服务器的共享文件夹
将本地电脑上的文件夹设为与服务器共享的文件夹,通常是在本地开启文件共享,并配置相应的权限,使服务器可以访问该文件夹。以下以 Windows 系统为例说明具体操作步骤: 一、在本地电脑上设置共享文件夹 选择文件夹 找到需要共享的文…...
自己搭建远程桌面服务器-RustDesk(小白版)
1.RustDesk简介 此软件主要功能为远程各种设备(其中包括Windows、macOS、Linux、iOS、Android、Web等) 支持文件传输(可直接拷贝远程电脑的文件,类似向日葵的远程文件) 支持内网穿透(支持端口映射&#…...
一文读懂服务器的HBA卡
什么是 HBA 卡 HBA 卡,全称主机总线适配器(Host Bus Adapter) ,是服务器与存储装置间的关键纽带,承担着输入 / 输出(I/O)处理及物理连接的重任。作为一种电路板或集成电路适配器,HBA…...
Android SystemUI——CarSystemBar车载状态栏(九)
上一篇文章我们介绍了车载开发中的 CarSystemUI,而车载开发中的状态栏也被 CarSystemBar 所取代,这里我们就来看看一下车载系统中的状态栏——CarSystemBar。 一、车载状态栏创建 1、CarSystemBar 源码位置:/packages/apps/Car/SystemUI/src/com/android/systemui/car/sy…...
干货答疑分享记录:as导入问题,LSP含义,分屏进入SplashScreen
背景: vip学员群经常会有学员遇到一些常见的android framework开发问题,近期收集整理一些疑问,主要有以下3个: 1、android studio对源码进行导入时候,老是无法跳转到系统source code 2、学员在群里询问dumpOtherPro…...
WPS数据分析000001
目录 一、表格的新建、保存、协作和分享 新建 保存 协作 二、认识WPS表格界面 三、认识WPS表格选项卡 开始选项卡 插入选项卡 页面布局选项卡 公式选项卡 数据选项卡 审阅选项卡 视图选项卡 会员专享选项卡 一、表格的新建、保存、协作和分享 新建 ctrlN------…...
单独编译QT子模块
单独编译QT子模块 系统 win qt-everywhere-src-5.12.12 下载源码: https://download.qt.io/archive/qt/5.12/5.12.12/single/ 参考: https://doc.qt.io/qt-5/windows-building.html 安装依赖 https://doc.qt.io/qt-5/windows-requirements.html Per…...
Ubuntu20.4和docker终端指令、安装Go环境、安装搜狗输入法、安装WPS2019:保姆级图文详解
目录 前言1、docker、node、curl版本查看终端命令1.1、查看docker版本1.2、查看node.js版本1.3、查看curl版本1.4、Ubuntu安装curl1.5、Ubuntu终端保存命令 2、安装docker-compose、Go语言2.1、安装docker-compose2.2、go语言安装步骤2.3、git版本查看 3、Ubuntu20.4安装搜狗输…...
HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (五、电影详情页的设计实现)
在上一篇文章中,完成了电影列表页的开发。接下来,将进入电影详情页的设计实现阶段。这个页面将展示电影的详细信息,包括电影海报、评分、简介以及相关影人等。将使用 HarmonyOS 提供的常用组件,并结合第三方库 nutpi/axios 来实现…...
电子杂志制作平台哪个好
作为一个热爱分享的人,我试过了好几个平台,终于找到了几款比较好用得电子杂志制作平台,都是操作界面很简洁,上手非常快的工具。 FLBOOK:这是一款在线制作H5电子画册软件,提供了各种类型的模板,可支持添加…...
1.写在前面
按照惯例,第一篇文章是要先介绍下专栏的风格、思路,以免需求不一致的同学误入,耽误大家时间。 本教程将系统的讲解若依前、后端的全部功能点,适合有面试需求的小伙伴,或者想提升自己能力的同学。本教程是免费教程。对源…...
JavaWeb 前端基础 html + CSS 快速入门 | 018
今日推荐语 指望别人的救赎,势必走向毁灭——波伏娃 日期 学习内容 打卡编号2025年01月17日JavaWeb 前端基础 html CSS018 前言 哈喽,我是菜鸟阿康。 今天 正式进入JavaWeb 的学习,简单学习 html CSS 这2各前端基础部分&am…...
redis做为缓存,mysql的数据如何与redis进行同步呢?
Redis作为缓存与MySQL之间的数据同步问题,特别是涉及到双写一致性(即缓存与数据库的写操作要保持一致)时,通常有两种常见的解决方案。它们分别适用于不同的一致性要求和延迟容忍度。以下是两种常见的解决方案的详细解释࿱…...
TCP 重传演进:TCP RACK Timer 能替代 RTO 吗
本文的建议适用于想改变 TCP 行为的新协议设计,还是那句话,不要抄 TCP 做 yet another TCP。 RTO 一直是 TCP 传输过程所要尽量避免的,因为它会将状态带入 Loss 进而 Go-Back-N,这是一个昂贵的操作。But 在 Fast-Retransmit 被引…...
React Native的现状与未来:从发展到展望
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
替换数字
目录 题目 思路 代码 题目 给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应…...
[cg] UE5 调试技巧
UE 中 rhi命令的提交是在render 线程,而graphics api 真正的执行是在rhi 线程, 今天想看下rhi的底层调用,但由于是通过task执行的,无法获取到render thread传入的地方,调试起来不太方便。 可通过开启下面的命令来调试 …...
Git相关命令
一:基础认识 1.Git 三种状态 Working Directory :本地工作目录,工作区Staging Area:添加文件,用于commit前,暂存区.git directory(Repository):本地仓库,存储commit数据࿰…...
uni-simple-router史上最全使用方法教程
在 uni-app 项目中,随着应用的复杂度增加,传统的路由管理方式可能无法满足需求,尤其是在多页面和权限控制等场景下。这时,使用像 uni-simple-router 这样的路由管理库可以简化开发流程👍,如权限控制、路由守…...
【ArcGIS微课1000例】0140:总览(鹰眼)、放大镜、查看器的用法
文章目录 一、总览工具二、放大镜工具三、查看器工具ArcGIS中提供了三种局部查看的工具: 总览(鹰眼)、放大镜、查看器,如下图所示,本文讲述这三种工具的使用方法。 一、总览工具 为了便于效果查看与比对,本实验采用全球影像数据(位于配套实验数据包中的0140.rar中),加…...
【Linux】【Vim】vim编辑器的用法
一、vim简介 Vim是一款功能强大且高度可定制的文本编辑器,广泛应用于Linux 和 Unix系统中。 它不仅继承了vi编辑器的所有特性,还增加了许多新的功能,如语法高亮、代码折叠、多级撤销等。 Vim有三种主要的工作模式: 命令模式&am…...
RabbitMQ实现延迟消息发送——实战篇
在项目中,我们经常需要使用消息队列来实现延迟任务,本篇文章就向各位介绍使用RabbitMQ如何实现延迟消息发送,由于是实战篇,所以不会讲太多理论的知识,还不太理解的可以先看看MQ的延迟消息的一个实现原理再来看这篇文章…...
《leetcode-runner》【图解】【源码】如何手搓一个debug调试器——架构
前文: 《leetcode-runner》如何手搓一个debug调试器——引言 文章目录 设计引入为什么这么设计存在难点1. 环境准备2. 调试程序 仓库地址:leetcode-runner 本文主要聚焦leetcode-runner对于debug功能的整体设计,并讲述设计原因以及存在的难点…...
G1原理—10.如何优化G1中的FGC
大纲 1.G1的FGC可以优化的点 2.一个bug导致的FGC(Kafka发送重试 subList导致List越来越大) 3.为什么G1的FGC比ParNew CMS要更严重 4.FGC的一些参数及优化思路 1.G1的FGC可以优化的点 (1)FGC的基本原理 (2)遇到FGC应该怎么处理 (3)应该如何操作来规避FGC (4)应该如何操…...
【专题一 递归】21. 合并两个有序链表
1.题目解析 2.讲解算法原理 解法:递归-> 重复的子问题 重复子问题 ->函数头的设计 合并两个有序链表--->Node dfs(l1,l2) 只关心某一个子问题在做什么事情 ->函数体的设计 比大小l1→next dfs( l1.next, l2)return l1 递归的出口 if(l1null)return l2…...
WebSocket——推送方案选型
一、前言:为何需要服务端主动推送? 在现代应用中,很多功能都依赖于“消息推送”。比如: 小红点提醒:我们经常在手机应用里看到的一个小红点提示,表示有新的消息或任务需要我们关注。新消息提醒࿱…...
Openresty 安装
1. 依赖包安装: # yum install readline-devel pcre-devel openssl-devel 2. 在系统中添加openresty的仓库: # sudo yum install yum-utils # sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo …...
回归预测 | MATLAB实TCN时间卷积神经网络多输入单输出回归预测
效果一览 基本介绍 回归预测 | MATLAB实TCN时间卷积神经网络多输入单输出回归预测 …………训练集误差指标………… 1.均方差(MSE):166116.6814 2.根均方差(RMSE):407.5741 3.平均绝对误差(MAE):302.5888 4.平均相对…...
TikTok专线服务器助力品牌营销新高度
在这个信息爆炸的时代,短视频平台如雨后春笋般涌现,TikTok便是其中的佼佼者。众多品牌纷纷涌入这个平台,试图借助其强大的用户基础和传播能力来提升知名度。而在这其中,IPIPGO直播专线的出现,为品牌在TikTok上的营销提…...
flutter VoidCallBack ValueChange<T> 的函数定义
在 Flutter 中,VoidCallback 和 ValueChanged<T> 是两种常用的回调函数类型,它们通常用于处理事件或传递数据。下面是它们的详细定义及使用方式。 1. VoidCallback 函数类型 VoidCallback 是一个没有参数也没有返回值的回调函数类型。它通常用于简单的事件处理,比如…...
pyspark连接clickhouse数据库的方式(其它数据库同样适用)
目录 一、背景简记二、pyspark连接clickhouse方式记录三、结语参考学习博文 一、背景简记 实际工作中,大部分所用的数据存储地址都是在数据库中,如我司现在常用的数据库是clickhouse,相关数据的统计分析都在此上操作。如果想用pyspark连接cl…...
当父级元素设置了flex 布局 ,两个子元素都设置了flex :1, 但是当子元素放不下的时候会溢出父元素怎么解决 (css 样式问题)
一、问题 遇到个样式问题,当父级元素设置了flex 布局 ,两个子元素都设置了flex :1, 但是当子元素放不下的时候会溢出父元素怎么解决 (拖拽浏览器 使页面变小) 二、解决方法 .father{min-height: 600px;width: 100%;display: flex…...
软件方法论--课程笔记(整理中)
C1:概览Introduction (1)软件的4个特性 一致性(Conformity):软件必须符合严格的规格和要求,包括与其他组件的接口和环境的连接,避免因为不一致导致无法复用或开发问题。 不可见性…...
从 0 开始实现一个 SpringBoot + Vue 项目
从 0 开始实现一个 SpringBoot Vue 项目 从 0 开始实现一个 SpringBoot Vue 项目 软件和工具创建 SpringBoot 后端项目创建 MySQL 数据库配置文件实现增删改查接口 Model 层mapper 层service 层controller 层测试 实现项目功能接口 代码测试 创建 Vue 前端 安装 Node.js配置…...
怎么修复损坏的U盘?而且不用格式化的方式!
当你插入U盘时,若电脑弹出“需要格式化才能使用”提示,且无法打开或读取其中的数据,说明U盘极有可能已经损坏。除此之外,若电脑在连接U盘后显示以下信息,也可能意味着U盘出现问题,需要修复损坏的U盘&#x…...
使用redis-cli命令实现redis crud操作
项目场景: 线上环境上redis中的key影响数据展示,需要删除。但环境特殊没办法通过 redis客户端工具直连。只能使用redis-cli命令来实现。 操作步骤: 1、确定redis安装的服务器; 2、找到redis的安装目录下 ##找到redis安装目…...
Kibana 控制台中提供语义、向量和混合搜索
作者:来自 Elastic Mark_Laney 想要将常规 Elasticsearch 查询与新的 AI 搜索功能结合起来吗?那么,你不需要连接到某个第三方的大型语言模型(LLM)吗?不。你可以使用 Elastic 的 ELSER 模型来改进现有搜索&a…...
设计模式-结构型-装饰器模式
装饰器模式(Decorator Pattern)是结构型设计模式中的一种,它允许你通过将对象封装在一个新的对象中,来动态地添加新的功能,而无需改变原对象的结构。装饰器模式的核心思想是“将功能附加到对象上”,它是一种…...
CAP:Serverless + AI 让应用开发更简单
AI 已被广泛视为推动行业进步的关键力量,其在各行业的落地步伐加快。企业在构建 AI 应用开发过程中经常会面临 AI 技术门槛过高、试错周期过长、GPU 资源昂贵且弹性能力不足、缺乏配套工具、业务与模型的开发运维过于割裂、缺乏定制化能力等挑战,成为企业…...
Redis超详细入门教程(基础篇)
目录 一、什么是Redis 二、安装Redis 1、Windows系统安装 2、Linux系统安装 三、Redis通用命令 四、Redis基本命令 五、五种数据结构类型 5.1、String类型 5.2、List集合类型 5.3、Set集合类型 5.4、Hash集合类型 5.5、Zset有序集合类型 六、总结 一、什么是Redi…...
对话 TDengine 解决方案中心总经理陈肃:构建技术与市场的桥梁
TD 小T导读 他是大数据领域的杰出专家,拥有超过十项一作发明专利,是中国通信行业标准《大数据 消息中间件技术要求与测试方法》的重要编写者,并凭借数据中间件领域的突出成就荣获 2019 年“CJK OSS Award”。他是腾讯云 TVP 专家和 TGO 鲲鹏会…...