八大排序算法
目录
- 八大排序算法
- 排序算法的稳定性
- 比较排序
- 插入排序
- 直接插入排序
- 希尔排序
- 希尔排序的时间复杂度计算
- 选择排序
- 直接选择排序
- 堆排序
- 交换排序
- 冒泡排序
- 快速排序
- 递归
- hoare版本
- 挖坑法
- lomuto前后指针
- 非递归
- 归并排序
- 排序性能对比
- 非比较排序
- 计数排序
- 比较排序算法总结
八大排序算法
排序算法的稳定性
稳定性:在排序过程中,相等元素的相对顺序在排序前后保持不变。
也就是说,若在待排序序列里有两个元素a和b,它们的值相等,
且在排序前a位于b之前,那么排序后a依旧处于b之前。
比较排序
比较排序顾名思义就是通过元素之间的大小比较来排序的方法。
插入排序
插入排序:将待排序元素插入到有序序列中,从而得到一个新的有序序列。
实际生活中,我们玩扑克牌时就用到了插入排序的思想。
直接插入排序
用 end 记录有序序列的最后一个位置,tmp 保存待排序序列中的第一个元素,
结合插入排序的思想来排序。
void InsertSort(int* arr, int n)
{for(int i = 0; i < n - 1; i++){//i < n - 1是因为当end = n - 2时就是在将最后一个待排序元素插入到有序序列中int end = i;//end用来记录有序序列的最后一个位置int tmp = arr[end + 1];//tmp保存待排序序列中的第一个元素//找待排元素应该插入的位置//当end<0时,说明待排元素比有序序列的最小元素还要小while(end >= 0){if(arr[end] > tmp)//说明待排元素的位置在有序序列中该元素的前面{//把有序序列中该元素向后移,给待排元素的插入腾出位置arr[end + 1] = arr[end];//找有序序列中的前一个元素end--;}else//说明已经找到了待排元素应该插入的位置,跳出循环break;}//将待排元素插入到有序序列中arr[end + 1] = tmp;}
}
下面是直接插入排序图解
直接插入排序总结
- 元素集合越接近有序,直接插入排序算法的时间效率越高
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:稳定
希尔排序
希尔排序(Shell Sort)是插入排序的一种改进版本,也被叫做缩小增量排序。
它的基本思路是通过一个初始增量gap(通常是gap = n / 3 + 1)将待排序列分
割成若干个子序列,分别对这些子序列进行直接插入排序;然后通过gap = gap / 3 + 1
使增量gap逐渐减小,子序列的长度逐渐增加,整个序列会变得越来越接近有序,
当增量gap减至1时,整个序列就被合并成一个,再进行一次直接插入排序,排序完成。
下面是希尔排序图解
void ShellSort(int* arr, int n)
{int gap = n;while(gap > 1){gap = gap / 3 + 1;//下面是直接插入排序的代码,只不过有小小的改变//因为直接插入排序每次移动1步,而希尔排序每次移动gap步for(int i = 0; i < n - gap; i++){int end = i;int tmp = arr[end + gap];while(end >= 0){if(arr[end] > tmp){arr[end + gap] = arr[end];end -= gap; }elsebreak;}arr[end + gap] = tmp;}}
}
希尔排序总结
- 希尔排序是对直接插入排序的优化。
- 当gap>1时都是预排序,目的是让数组更接近有序。当gap == 1时,
数组已经很接近有序了,再进行直接插入排序会很快。- 时间复杂度:O(N^1.3)
- 空间复杂度:O(1)
- 稳定性:不稳定
希尔排序的时间复杂度计算
外层循环:while(gap > 1)
时间复杂度可以直接给出为:O(logN)
内层循环:
忽略+1的影响,gap = gap / 3
希尔排序时间复杂度不好计算,因为gap 的取值很多,导致很难去计算,因此很多书中给出的
希尔排序的时间复杂度都不固定。《数据结构(C语⾔版)》—严蔚敏书中给出的时间复杂度为:
选择排序
选择排序的基本思想:每一次从待排序列中选出最小(或最大)的一个元素,
存放在序列的起始位置,直到待排元素全部排完。
直接选择排序
- 设begin和end分别为待排序列的首尾位置,在待排序列arr[begin]~arr[end]中找最大和最小元素。
- 若最小和最大元素不是待排序列的首尾元素,就让最小和最大元素与待排序列的首尾元素交换。
- begin++,end–为下一次选择排序做准备,重复上述步骤。
//直接选择排序
void SelectSort(int* arr, int n)
{//记录待排序列的首尾位置int begin = 0;int end = n - 1;//如果begin >= end说明序列已经排好序while (begin < end){//假设待排序列中最大和最小元素的位置都在首位置int maxi = begin, mini = begin;//找待排序列中最大和最小元素的位置for (int i = begin + 1; i <= end; i++){if (arr[i] > arr[maxi])maxi = i;if (arr[i] < arr[mini])mini = i;}//让最小元素与首元素交换,最大元素与尾元素交换//如果最大元素就是首元素的话,第一次交换会把最//大元素交换到mini位置处,所以要让maxi = miniif (maxi == begin)maxi = mini;Swap(&arr[begin], &arr[mini]);Swap(&arr[end], &arr[maxi]);//为下一次选择排序做准备begin++;end--;}
}
下面是直接选择排序的图解
直接选择排序总结:
时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:不稳定
堆排序
堆排序(Heap Sort)是一种基于二叉堆数据结构的比较排序算法,其基本思想是先将
待排序的序列构建成一个最大堆(对于升序排序),然后将堆顶元素(最大值)与堆的
最后一个元素交换,接着将剩余的元素重新调整为最大堆,重复这个过程,直到整个序列有序。
//向下调整算法 O(logN)
void AdjustDown(int* arr, int n, int parent)
{int child = parent * 2 + 1;//左孩子while (child < n){//小堆:<//大堆:>if (child + 1 < n && arr[child + 1] > arr[child])child++;//小堆:<//大堆:>if (arr[parent] > arr[child])break;//<=就交换了,所以稳定性:不稳定Swap(&arr[parent], &arr[child]);parent = child;child = parent * 2 + 1;}
}//向上调整算法 O(logN)
void AdjustUp(int* arr, int child)
{int parent = (child - 1) / 2;while (parent >= 0){//大堆:>//小堆:<if (arr[parent] > arr[child])break;Swap(&arr[parent], &arr[child]);child = parent;parent = (child - 1) / 2;}
}//堆排序
void HeapSort(int* arr, int n)
{//升序 - 建大堆//降序 - 建小堆//建堆 - 向下调整法 O(N)for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, n, i);}建堆 - 向上调整法 O(NlogN)//for (int i = 1; i < n; i++)//{// AdjustUp(arr, i);//}//堆排序 O(NlogN)int end = n - 1;while (end > 0){Swap(&arr[0], &arr[end]);AdjustDown(arr, end, 0);end--;}
}
堆排序总结:
时间复杂度:O(NlogN)
空间复杂度:O(1)
稳定性:不稳定
交换排序
交换排序基本思想:通过比较序列中元素的大小,根据比较结果
对元素位置进行交换操作,逐步让序列达到有序状态。
冒泡排序
void BubbleSort(int* arr, int n)
{for (int i = 0; i < n - 1; i++){int flag = 0;for (int j = 0; j < n - 1 - i; j++){if (arr[j] > arr[j + 1]){Swap(&arr[j], &arr[j + 1]);flag = 1;}}if (flag == 0)break;}
}
冒泡排序总结:
时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:稳定
快速排序
快速排序(Quick Sort)是一种高效的排序算法,它采用分治法(Divide and Conquer)策略。
基本思想是从待排序序列中挑选一个元素作为基准(pivot),然后将序列划分为两部分,
使得左边部分的所有元素都小于等于基准,右边部分的所有元素都大于等于基准,接着
分别对左右两部分递归地进行快速排序,最终得到一个有序序列。
递归
void QuickSort(int* arr, int left, int right)
{//递归出口if(left >= right)return;//接收一个基准值的位置int pi = _QuickSort(arr, left, right);//将序列划分成两部分:[left, pi-1] [pi+1, right]//递归左右序列QuickSort(arr, left, pi - 1);QuickSort(arr, pi + 1, right);
}
_QuickSort有以下三个写法
hoare版本
hoare版本的基本思路
- 假定首元素为基准值,让left++
- 在[left,right]中,先从右向左找不大于基准值的值,再从左向右找不小于基准值的值,
找到后,进行交换,再让left++和right–。- 循环结束,交换基准值和right指向的值,使得左边部分的所有元素都小于等于基准值,
右边部分的所有元素都大于等于基准值。
int _QuickSort(int* arr, int left, int right)
{//假设首元素是基准值,记录其位置int pi = left;//让left指向下一个元素的位置left++;while (left <= right){//从右向左找不大于基准值的值while (left <= right && arr[right] > arr[pi])right--;//从左向右找不小于基准值的值while (left <= right && arr[left] < arr[pi])left++;//找到后,进行交换,更新left和rightif (left <= right)Swap(&arr[left++], &arr[right--]);}//交换基准值和right指向的值//使得左边部分的所有元素都小于等于基准,右边部分的所有元素都大于等于基准Swap(&arr[pi], &arr[right]);//返回基准值的下标return right;
}
问题一:为什么循环的条件是 left<=right ?
问题二:为什么跳出循环时,交换基准值和right指向的值?
当left>right时,即right走到left的左侧,而left扫描过的数据均不大于基准值,
因此right指向的数据一定不大于基准值,且是序列中最右边的不大于基准值的元素。
挖坑法
挖坑法的基本思路
- 假设首元素是基准值,并保存基准值,“坑”的位置就是基准值的位置。
- 从右向左找比基准值小的值,将小于基准值的元素填入坑,保存新的“坑”的位置,
丛左向右找比基准值大的值,将大于基准值的元素填入坑,保存新的“坑”的位置。- 当left==right时,跳出循环,此时left和right都指向坑的位置,将基准值放入该位置。
int _QuickSort(int* arr, int left, int right)
{//假设首元素是基准值,并保存基准值int pivot = arr[left];//“坑”的位置就是基准值的位置int hole = left;while (left < right){//从右向左找比基准值小的值while (left < right && arr[right] >= pivot)right--;//将小于基准值的元素填入坑if (left < right){arr[hole] = arr[right];//保存新的“坑”的位置hole = right;}//丛左向右找比基准值大的值while (left < right && arr[left] <= pivot)left++;//将大于基准值的元素填入坑if (left < right){arr[hole] = arr[left];//保存新的“坑”的位置hole = left;}}//当left==right时,跳出循环,此时left和right都指向坑的位置//将基准值放入该位置,使得左边部分的所有元素都小于等于基准,//右边部分的所有元素都大于等于基准arr[hole] = pivot;//返回基准值的位置return hole;
}
lomuto前后指针
lomuto前后指针的基本思路
- 假设首元素是基准值,记录其位置
- 创建前后指针prev和cur
- 从左向右找比基准值小的进行交换,使得小的都在基准值左边
- 交换基准值和prev指向的值
int _QuickSort(int* arr, int left, int right)
{//假设首元素是基准值,记录其位置int pi = left;//创建前后指针prev和curint prev = left, cur = left + 1;//只有cur遍历完数组才会出循环while (cur <= right){//从左向右找比基准值小的进行交换,使得小的都在基准值左边if (arr[cur] < arr[pi] && ++prev != cur)Swap(&arr[cur], &arr[prev]);cur++;}//交换基准值和prev指向的值//使得左边部分的所有元素都小于基准,右边部分的所有元素都大于等于基准Swap(&arr[pi], &arr[prev]);//返回基准值的下标return prev;
}
快速排序总结:
- 时间复杂度:O(NlogN)
- 空间复杂度:O(logN)
- 稳定性:不稳定
非递归
非递归版本的快速排序需要借助数据结构:栈
void QuickSortNonR(int* arr, int left, int right)
{//借助数据结构 - 栈//创建栈ST st;//初始化STInit(&st);//让首尾元素下标入栈,注意入栈和出栈顺序STPush(&st, right);STPush(&st, left);//栈非空进循环while (STSize(&st)){//保存首尾元素下标int begin = STTop(&st);STPop(&st);int end = STTop(&st);STPop(&st);//利用lomuto前后指针思想int pi = begin;int prev = begin, cur = begin + 1;while (cur <= end){if (arr[cur] < arr[pi] && ++prev != cur)Swap(&arr[cur], &arr[prev]);cur++;}Swap(&arr[prev], &arr[pi]);//更新基准值的位置pi = prev;//为下一次排序排序做准备//[begin, pi - 1] pi [pi + 1, end]if (begin < pi - 1){STPush(&st, pi - 1);STPush(&st, begin);}if (pi + 1 < end){STPush(&st, end);STPush(&st, pi + 1);}}//销毁STDestroy(&st);
}
归并排序
归并排序(Merge Sort)是一种采用分治法(Divide and Conquer)的经典排序算法。
它的基本思想是将一个大问题分解为多个小问题,分别解决这些小问题,最后将小问题
的解合并起来得到原问题的解。具体来说,归并排序将一个数组分成两个子数组,分别
对这两个子数组进行排序,然后将排好序的子数组合并成一个最终的有序数组。
下面是归并排序图解
void _MergeSort(int* arr, int left, int right, int* tmp)
{//1.分解//递归出口if (left >= right)return;int mid = left + (right - left) / 2;//递归分解左右序列:[left, mid] [mid+1, right]_MergeSort(arr, left, mid, tmp);_MergeSort(arr, mid + 1, right, tmp);//2.合并//合并左右两个有序序列//为了防止合并时覆盖有效数据,需要一个临时数组tmpint begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;//[begin1, end1] [begin2, end2]int index = begin1;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2])tmp[index++] = arr[begin1++];elsetmp[index++] = arr[begin2++];}while (begin1 <= end1){tmp[index++] = arr[begin1++];}while (begin2 <= end2){tmp[index++] = arr[begin2++];}//3.将tmp中有序的数据导入到原数组中//[left, right]for (int i = left; i <= right; i++){arr[i] = tmp[i];}
}void MergeSort(int* arr, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");exit(1);}_MergeSort(arr, 0, n - 1, tmp);free(tmp);tmp = NULL;
}
归并排序总结:
- 时间复杂度:O(NlogN)
- 空间复杂度:O(N)
- 稳定性:稳定
排序性能对比
void TestOP()
{srand(time(0));const int N = 100000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);int* a7 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin3 = clock();SelectSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1);int end5 = clock();int begin6 = clock();MergeSort(a6, N);int end6 = clock();int begin7 = clock();BubbleSort(a7, N);int end7 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);printf("BubbleSort:%d\n", end7 - begin7);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);
}
非比较排序
非比较排序不需要通过元素之间的大小比较来排序。
计数排序
计数排序又称为鸽巢原理,其核心思想是通过统计每个元素在序列中出现的次数,
进而确定每个元素在排序后序列中的位置。该算法适用于整数序列,且当待排序元素
的值范围较小时,计数排序的效率较高。
void CountSort(int* arr, int n)
{//找arr数组中的最大值和最小值,用来确定申请的新数组的空间大小int max = arr[0], min = arr[0];for (int i = 1; i < n; i++){if (arr[i] > max)max = arr[i];if (arr[i] < min)min = arr[i];}//所以新数组的大小为rangeint range = max - min + 1;int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail");return;}memset(count, 0, range * sizeof(int));//初始化为0//统计原数组中每个元素出现的次数for (int i = 0; i < n; i++){count[arr[i] - min]++;}//排序int j = 0;for (int i = 0; i < range; i++){while (count[i]--){arr[j++] = i + min;}}
}
计数排序总结:
- 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。
- 时间复杂度:O(N + range)
- 空间复杂度:O(range)
- 稳定性:稳定
比较排序算法总结
相关文章:
八大排序算法
目录 八大排序算法排序算法的稳定性比较排序插入排序直接插入排序希尔排序希尔排序的时间复杂度计算 选择排序直接选择排序堆排序 交换排序冒泡排序快速排序递归hoare版本挖坑法lomuto前后指针 非递归 归并排序排序性能对比 非比较排序计数排序 比较排序算法总结 八大排序算法 …...
搭建一个Spring Boot聚合项目
1. 创建父项目 打开IntelliJ IDEA,选择 New Project。 在创建向导中选择 Maven,确保选中 Create from archetype,选择 org.apache.maven.archetypes:maven-archetype-quickstart。 填写项目信息: GroupId:com.exampl…...
Google A2A协议解析:构建分布式异构多Agent系统
一、A2A 是什么?有什么用? 1.1 A2A 是什么? A2A(Agent-to-Agent Protocol)是Google最新推出的一项开源协议,旨在为AI智能体(Agents)提供标准化的通信方式。它允许不同框架…...
【Android读书笔记】读书笔记记录
文章目录 一. Android开发艺术探索1. Activity的生命周期和启动模式1.1 生命周期全面分析 一. Android开发艺术探索 1. Activity的生命周期和启动模式 1.1 生命周期全面分析 onPause和onStop onPause后会快速调用onStop,极端条件下直接调用onResume 当用户打开新…...
支持selenium的chrome driver更新到135.0.7049.84
最近chrome释放新版本:135.0.7049.84 如果运行selenium自动化测试出现以下问题,是需要升级chromedriver才可以解决的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only su…...
【玩泰山派】MISC(杂项)- 使用vscode远程连接泰山派进行开发
文章目录 前言流程1、安装、启动sshd2、配置一下允许root登录3、vscode中配置1、安装remote插件2、登录 **注意** 前言 有时候要在开发板中写一写代码,直接在终端中使用vim这种工具有时候也不是很方便。这里准备使用vscode去通过ssh远程连接泰山派去操作࿰…...
利用阿里云企业邮箱服务实现Python群发邮件
目录 一、阿里云企业邮箱群发邮件全流程实现 1. 准备工作与环境配置 2. 收件人列表管理 3. 邮件内容构建 4. 附件添加实现 5. 邮件发送核心逻辑 二、开发过程中遇到的问题与解决方案 1. 附件发送失败问题 2. 中文文件名乱码问题 3. 企业邮箱认证失败 三、完整工作流…...
中文编码,GB系列,UTF
图片来源:https://zhuanlan.zhihu.com/p/701690894 文章目录 ASCIIGB系列编码UTF编码 ASCII American Standard Code for Information Interchange 一个字节,但其实只用了一半: 128个字符 GB系列编码 “国标” 和ASCII是兼容的。 GB2312…...
车载以太网-TLS
文章目录 车载以太网与TLS的技术背景核心定位车载以太网TLS的技术架构车载TLS的核心安全机制TLS报文结构详解TLS工作机制密钥交换与计算流程标题完整握手流程(1-RTT)数据传输加密流程车载TLS的独特优化策略车载TLS的安全威胁相关标准车载以太网TLS(Transport Layer Security…...
【大英赛】大英赛准备笔记
听力 总结 提醒专注 一题一个听力时,听是重点 抓紧时间往后审题 比较容易的部分:secA & secD中的dictation,在大致审当前的基础上,分别利用这个时间提前看后面的secB√& summery secA 听之前应当大致审选项&#x…...
有序数组的平方
暴力排序 每个数平方以后排个序 class Solution { public:vector<int> sortedSquares(vector<int>& nums) {int slow0,fast0;int nnums.size();while(fast<n){nums[slow]nums[fast]*nums[fast];fast;slow;}sort(nums.begin(),nums.end());return nums;} }…...
Python基于Django的房屋信息可视化及价格预测系统(附源码,文档说明)
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
【5G-A学习】ISAC通信感知一体化学习小记
通信感知一体化(Integrated Sensing and Communication, ISAC)是一种将无线通信与环境感知功能深度融合的技术,通过共享硬件、频谱和信号处理流程,实现通信与感知的协同增效。其核心原理及无人机与飞鸟的识别方式如下:…...
深入解析@Validated注解:Spring 验证机制的核心工具
一、注解出处与核心定位 1. 注解来源 • 所属框架:Validated 是 Spring Framework 提供的注解(org.springframework.validation.annotation 包下)。 • 核心定位: 作为 Spring 对 JSR-380(Bean Validation 2.0&#…...
学生考勤管理系统(jsp+ssh+mysql5.x)含文档
学生考勤管理系统(jspsshmysql5.x)含万字详细文档 学生考勤管理系统是一个用于管理学生出勤和请假的系统,系统登录页面提供账号和密码输入框,用户可以选择角色进行登录。系统主菜单包括班级管理、用户管理、课程表管理和考勤情况…...
【响应式编程】Reactor 常用操作符与使用指南
文章目录 一、创建操作符1. just —— 创建包含指定元素的流2. fromIterable —— 从集合创建 Flux3. empty —— 创建空的 Flux 或 Mono4. fromArray —— 从数组创建 Flux5. fromStream —— 从 Java 8 Stream 创建 Flux6. create —— 使用 FluxSink 手动发射元素7. generat…...
为什么我们需要if __name__ == __main__:
[目录] 0.前言 1.什么是 __name__? 2.if __name__ __main__: 的作用 3.为何Windows更需if __name__ ?前言 if __name__ __main__: 是 Python 中一个非常重要的惯用法,尤其在使用 multiprocessing 模块或编写可导入的模块时。它的作用是区分…...
Week 1: Time Complexity, Rectangle Geometry
问题集 Square PastureBucket BrigadeBlocked BillboardBlocked Billboard IIWord ProcessorDo You Know Your ABCs?The Cow-SignalD3C - White Sheet 视频解析 Square Pasture Bucket Brigade Blocked Billboard Blocked Billboard II Word Processor Do You Know Your AB…...
论文学习:《通过基于元学习的图变换探索冷启动场景下的药物-靶标相互作用预测》
原文标题:Exploring drug-target interaction prediction on cold-start scenarios via meta-learning-based graph transformer 原文链接:https://www.sciencedirect.com/science/article/pii/S1046202324002470 药物-靶点相互作用(DTI&…...
STM32 HAL库 OLED驱动实现
一、概述 1.1 OLED 显示屏简介 OLED(Organic Light - Emitting Diode)即有机发光二极管,与传统的 LCD 显示屏相比,OLED 具有自发光、视角广、响应速度快、对比度高、功耗低等优点。在嵌入式系统中,OLED 显示屏常被用…...
UE5蓝图之间的通信------接口
一、创建蓝图接口 二、双击创建的蓝图接口,添加函数,并重命名新函数。 三、在一个蓝图(如玩家角色蓝图)中实现接口,如下图: 步骤一:点击类设置 步骤二:在细节面板已经实现的接口中…...
封装Tcp Socket
封装Tcp Socket 0. 前言1. Socket.hpp2. 简单的使用介绍 0. 前言 本文中用到的Log.hpp在笔者的历史文章中都有涉及,这里就不再粘贴源码了,学习地址如下:https://blog.csdn.net/weixin_73870552/article/details/145434855?spm1001.2014.3001…...
深入解析 Android 图形系统:Canvas、Skia、OpenGL 与 SurfaceFlinger 的协作
在 Android 应用开发中,流畅的 UI 渲染是用户体验的核心。但你是否好奇,一个简单的 View 是如何从代码中的 onDraw() 方法一步步变成屏幕上的像素的?本文将从底层图形系统的视角,解析 Android 中 Canvas、Skia、OpenGL ES 和 Surf…...
LeetCode每日一题4.13
1922. 统计好数字的数目 问题 问题分析 题目要求我们找到长度为 n 且满足特定条件(偶数下标处为偶数,奇数下标处为质数)的数字字符串的总数,并对 (10^9 7) 取余。 思路 1.枚举 生成所有可能的数字字符串:对于长度…...
Java学习——day29(并发控制高级工具与设计模式)
文章目录 1. 并发控制高级工具简介1.1 CountDownLatch1.2 CyclicBarrier1.3 Semaphore1.4 并发设计模式 2. 扩展生产者—消费者示例2.1 示例代码 3. 代码详解3.1 主类 ExtendedProducerConsumerDemo3.2 Buffer 类3.3 Producer 类3.4 Consumer 类 4. 编译与运行结果4.1 编译4.2 …...
使用FormData格式上传图片
为什么要使用FormData格式上传图片 1. 为什么使用 FormData? FormData 是一种专门用于构建表单数据的对象,它能够以 multipart/form-data 格式发送数据,这是文件上传的标准格式。以下是使用 FormData 的主要原因: 简单易用 直…...
Tkinter表格与列表框应用
在图形用户界面(GUI)开发中,表格和列表框是常用的控件,用于显示和管理大量的数据。Tkinter提供了Listbox控件来显示简单的列表数据,而对于更复杂的表格数据,可以使用Treeview控件(属于ttk模块)来实现。这一章将介绍如何使用Listbox和Treeview来显示和操作数据,帮助您处…...
【Excel】数据透视表月度数据排序不正确
【问题】 插入数据透视表后,月度列显示的日期,是按照文本格式排序的,显然与实际月份排序并不相符。 【目的】 按照从1月份到12月份进行自然月度排序。 【方法】 步骤一: 在任意一处,输入“1月”-“12月”&#…...
HCIP第十天
OSPF的数据包 OSPF是跨层封装协议,直接封装在网络层之上 --- 需要IP协议使用一个协议号来标定 OSPF --- 89 OSPF的头部 版本 --- OSPF的版本 --- 2 类型 --- OSPF数据包的类型 --- hello -- 1 DBD -- 2 LSR -- 3 LSU -- 4 LSACK -- 5 路由器ID --- RID --- 携带的是发出O…...
Vue2,Vue3知识大全
Vue 1.了解vue,快速上手 vue是一个用于构建用户的界面的渐进式框架. vue的两种使用方法: vue核心包开发 场景:局部模块改造 vue核心包&vue插件 工程化开发 场景:整站开发 1.创建一个vue实例: 2.插值表达式 1.插值表达式是一种Vue的模版语法 作用:利用表达式进行插值…...
java面向对象02:回顾方法
回顾方法及加深 定义方法 修饰符 返回类型 break:跳出switch和return的区别 方法名 参数列表 package com.oop.demo01;//Demo01类 public class Demo01 {//main方法public static void main(String[] args) {}/*修饰符 返回值类型 方法名(...){//方法体return…...
【Ubuntu】【树莓派】Linux系统的远程终端登录、远程图形桌面访问、 X图形窗口访问和文件传输操作
目录 一、Ubuntu远程终端并实现文件上传下载 1.1Ubuntu桥接模式设置和新用户的创建 1.2Ubuntu的远程登录并上传和下载文件 1.3在Xming中进行Ubuntu的图形访问 二、树莓派远程登录并实现文件上传下载 2.1树莓派在putty上的远程登录 2.2使用ftp远程登录并实现文件上传下载…...
Linux Kernel 2
地址空间(Address Space) 一、物理地址空间(Physical Address Space) 物理地址空间 是指 RAM 和设备内存 在系统内存总线上所呈现的地址布局。 举例:在典型的 32 32 32 位 Intel 架构中, RAM(…...
二.springBoot项目集成ElasticSearch及使用
二.springBoot项目集成ElasticSearch及使用 1.依赖引入2.ElasticSearch常见用法 1.依赖引入 <!--elasticsearch搜索引擎--> <!--高版本7.0后TransportClient已被淘汰,用rest-high-level-client代替--> <dependency><groupId>org.elasticse…...
从三次方程到复平面:复数概念的奇妙演进(一)
注:本文为 “复数 | 历史 / 演进” 相关文章合辑。 因 csdn 篇幅限制分篇连载,此为第一篇。 生料,不同的文章不同的点。 机翻,未校。 Reflections on the History of Complex Numbers 复数的历史回顾 The first occurrence o…...
Day52 | 6. Z 字形变换、8. 字符串转换整数 (atoi)、22. 括号生成、38. 外观数列
6. Z 字形变换 题目链接:6. Z 字形变换 - 力扣(LeetCode) 题目难度:中等 代码: class Solution {public String convert(String s, int numRows) {if(numRows<2) return s;List<StringBuilder> rowsnew A…...
每日OJ_牛客_ruby和薯条_排序+二分/滑动窗口_C++_Java
目录 ruby和薯条_排序二分/滑动窗口 题目解析 C代码 Java代码 ruby和薯条_排序二分/滑动窗口 ruby和薯条 描述: ruby很喜欢吃薯条。 有一天,她拿出了n根薯条。第i根薯条的长度为ai。 ruby认为,若两根薯条的长度之差在l和r之间ÿ…...
快速幂运算
快速幂运算 一、快速幂运算快速幂运算(Exponentiation by Squaring)基本思想算法实现(②③为非递归)① 递归运算② 普通 除模运算(不带 **模数** 与 带 **模数**)③ 按位与运算 使用示例示例代码 复杂度分析…...
vue @import引入CSS scoped无效 造成全局样式污染
引入css文件导致全局样式污染 1.写在单组件的style里面css样式,如果标签内不加scoped可能会影响其他组件的样式 <style lang"scss" scoped> </style> 2.通过import引入的外部css文件,这种引入方式是全局的,也会影响其…...
基于Flask-Login简单登录和权限控制实践
1. 关于Flask-Login Flask-Login 是一个为python Flask Web框架设计的扩展,用于管理用户会话(用户登录状态)。它提供了简单的接口来处理用户登录、注销、记住用户等功能,同时确保用户会话的安全性。以下是 Flask-Login 的一些关键特性和功能: 1.1. 主要功能 用户会话管理…...
文件流---------获取文件的内容到控制台
总流程:先创建一个文本文件------->里面写入一些内容(纯字母和字母加文字)-----------> 然后通过输入流获取文件里面的内容,两种方式。 1.第一种,获取单个的字符 ,先创建文件 ,java.txt…...
idea 2024 build菜单不见了
Q如题 idea 2024 新版UI添加build和recompile菜单 A如图,右键顶部栏之后,点击Add to Main Toolbar菜单,在里面就能找到Build菜单,添加接口。 Recompile菜单的话在Customize Toolbar中搜索添加才行。...
深入理解计算机操作系统(持续更新中...)
文章目录 一、计算机系统漫游1.1信息就是位上下文 一、计算机系统漫游 1.1信息就是位上下文 源程序实际上就是一个由值0和1组成的位(又称为比特),八个位被组织成一组,称为字节。每个字节表示程序中的某些文本字符 大部分现代计…...
[dp8_子数组] 乘积为正数的最长子数组长度 | 等差数列划分 | 最长湍流子数组
目录 1.乘积为正数的最长子数组长度 2.等差数列划分 3.最长湍流子数组 写代码做到,只用维护好自己的一小步 1.乘积为正数的最长子数组长度 链接:1567. 乘积为正数的最长子数组长度 给你一个整数数组 nums ,请你求出乘积为正数的最长子数…...
量子机器学习(Quantum Machine Learning, QML)在优化测试组合
量子机器学习(Quantum Machine Learning, QML)在优化测试组合选择中展现出显著潜力,通过量子计算的并行性和量子态叠加特性,可高效解决传统方法难以处理的组合爆炸问题。以下是其技术实现路径、优势及落地案例: 一、QML优化测试组合的核心原理 1. 量子并行性加速搜索 经典…...
Go语言Slice切片底层
Go语言(Golang)中切片(slice)的相关知识、包括切片与数组的关系、底层结构、扩容机制、以及切片在函数传递、截取、增删元素、拷贝等操作中的特性。并给出了相关代码示例和一道面试题。关键要点包括: 数组特性…...
导入 Excel 批量替换文件夹名称
文件夹重命名的需求是多种多样的,前面我们介绍过按照规则修改文件夹名称的方法。但是在某些场景下,这个方法可能是不适用的,比如我们修改文件夹的规则是多种多样的,是无规律的。那我们应该怎么做呢?今天我们就给大家介…...
数据库或表数据迁移(使用Navicat迁移MySQL数据库表数据)
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 数据库或表数据迁移(使用Navicat…...
Matlab Add Legend To Graph-图例添加到图
Add Legeng To Graph: Matlab的legend()函数-图例添加到图 将图例添加到图 ,图例是标记绘制在图上的数据序列的有用方法。 下列示例说明如何创建图例并进行一些常见修改,例如更改位置、设置字体大小以及添加标题。您还可以创建具有多列的图…...
【Linux】what is pam?PAM模块学习笔记
文章目录 1. pam模块简介2. pam验证的工作流程3. pam模块配置文件3.1 配置文件的格式3.1.1 验证类别type3.1.2 验证的控制标识 control flag3.1.3 pam模块 4. login的PAM验证机制流程5. 补充:其他pam相关文件6. 参考内容 1. pam模块简介 PAM: Pluggable Authentica…...