排序-八大排序FollowUp

FollowUp

1.插入排序

(1).直接插入排序

时间复杂度:
最坏情况下:0(n^2)
最好情况下:0(n)
当数据越有序 排序越快

适用于: 待排序序列 已经基本上趋于有序了!
空间复杂度:0(1)
稳定性:稳定的

   public static void insertSort(int[] array){for (int i = 1; i < array.length; i++) {int tmp = array[i];int j = i - 1;for (; j >= 0 ; j--) {//这里加不加等号 和稳定有关系// 但是:本身就是一个稳定的排序 可以实现为不稳定的排序// 但是 本身就是一个不稳定的排序 是不可能变成一个稳定的排序的if(array[j] > tmp){array[j + 1] = array[j];}else {break;}}array[j+1] = tmp;}}

 (2).希尔排序(缩小增量排序)

重点是最后还是会把整体作一组来直接插入排序

  public static void shellSort(int[] array){int gap = array.length;while(gap > 1){shell(array,gap);gap /= 2;}}public static void shell(int[] array, int gap){for (int i = gap; i < array.length; i++) {int tmp = array[i];int j = i - gap;for (;j >= 0; j -= gap) {if(array[j] > tmp){array[j+gap] = array[j];}else {break;}}array[j+gap] = tmp;}}

 2.选择排序

(1).直接选择排序

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素
若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

    public static void selectSort(int[] array){for (int i = 0; i < array.length; i++) {int mixIndex = i;for (int j = i+1; j < array.length; j++) {if(array[mixIndex] > array[j]){mixIndex = j;}}int tmp = array[i];array[i] = array[mixIndex];array[mixIndex] = tmp;}}

【直接选择排序的特性总结】
1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:不稳定

(2.)双向选择排序:

 public static void selectSort2(int[] array){int left = 0;int right = array.length-1;while(left < right){int minIndex = left;int maxIndex = left;for (int i = left+1; i < right; i++) {if(array[i] > array[maxIndex]){maxIndex = i;}if(array[i] < array[minIndex]){minIndex = i;}swap(array,left,minIndex);//防止最大的是在第一个的时候if(maxIndex == left){maxIndex = minIndex;}swap(array,right,maxIndex);left++;right--;}}}

(3).堆排序

具体的思路在PriorityQueue(一)——用堆实现优先级队列

    public static void heapSort(int[] array){creatHeap(array);int end = array.length-1;while(end > 0){swap(array,0,end);siftDown(array,0,end);end--;}}private static void creatHeap(int[] array) {for (int parent = (array.length-1-1)/2; parent >= 0 ; parent--) {siftDown(array,parent,array.length);}}private static void siftDown(int[] array,int parent,int len) {int child = 2*parent + 1;while(child < len){if(child +1 < len && array[child] < array[child+1]){child++;}if(array[child] > array[parent]){swap(array,child,parent);parent = child;child = 2*parent + 1;}else {break;}}}
public static void swap(int[] array, int i, int j){int tmp = array[i];array[i] = array[j];array[j] = tmp;}

3.交换排序

(1).冒泡排序

优化:

时间复杂度:0(N^2)
如果加了优化:最好情况下 可以达到0(n)

空间复杂度:0(1)

稳定性:稳定的排序
优化:每一趟都需要判断 上一趟 有没有交换

    public static void bubbleSort(int[] array){for (int i = 0; i < array.length-1; i++) {boolean flg = false;for (int j = 0; j < array.length -1 - i ; j++) {if(array[j] > array[j+1]){swap(array,j,j+1);flg =true;}}//说明上一趟没有交换,也就是有序了if(!flg){break;}}}public static void swap(int[] array, int i, int j){int tmp = array[i];array[i] = array[j];array[j] = tmp;}

(2).快速排序 

 
时间复杂度
最好的情况下:0(N*logN) 最坏情况下:0(N^2)逆宇|有序空间复杂度:
最好的情况下:0(logN) 最坏情况下:0(N)逆序/有序
稳定性:不稳定

快排最好和最坏情况分析

Hoare法

记录下key L和R相向出发,R找比Key小的值,L找比Key大的值,R先找找到后,L再找,两个找到交换;直到L和R相遇,相遇的位置为最后L找到的小于Key的值(让R先找的原因),此时的L就是pivot ,将Key和L交换

然后以pivot为中点,将它左右两边的循环以上操作也就是递归直到传入的L和R为相同的,那么任何一个以pivot为中点的数组都变成有序的了

pivot指的是l和r相遇的位置 

  public static void  quickSort(int[] array){quick(array,0, array.length-1);}private static void quick(int[] array,int start,int end) {if(start >= end){return;}int pivot = partitionHoare(array,start,end);quick(array,start,pivot-1);quick(array,pivot+1,end);}private static int partitionHoare(int[] array, int left, int right) {int tmp = array[left];int i = left;while(left < right){while(left < right && array[right] >= tmp){right--;}while (left < right && array[left] <= tmp){left++;}swap(array,left,right);}swap(array,i,left);return left;}

总结:

 

 

 挖坑法

向将L的第一个位置为key,也就是坑位置,然后还是R先走找到比key小的就将R下标的值给坑位,此时R为坑位,L再走,找到比L大的值,放到坑位,L此时变为坑位,直到R和L相遇,还是保证L和R相遇的时候,是R找的比Key小的放到坑位里,然后将相遇的坑位放入Key

   public static void  quickSort(int[] array){quick(array,0, array.length-1);}private static void quick(int[] array,int start,int end) {if(start >= end){return;}int pivot = partitionHole(array,start,end);quick(array,start,pivot-1);quick(array,pivot+1,end);}private static int partitionHole(int[] array, int left, int right) {int tmp = array[left];int t = left;while(left < right){while(left < right && array[right] >= tmp){right--;}array[left] = array[right];while (left < right && array[left] <= tmp){left++;}array[right] = array[left];}array[left] = tmp;return left;}

总结: 

前后指针法

cur指向left加1的位置,prev指向left的位置,cur往前走,当遇到一个小于left下标值,并且此时cur和prev指向的不是同一个位置,那么cur和prev下标的值互换,直到cur超过right此时将prev和left下标的值互换,并返回prev,即是相对的中间位置

 public static void quickSort(int[] array) {quick(array, 0, array.length - 1);}
public static int partition(int[] array, int left, int right){int prev = left;int cur = left + 1;while (cur <= right){if(array[cur] < array[left] && array[++prev] != array[cur]){swap(array,prev,cur);}cur++;}swap(array,left,prev);return prev;}private static void quick(int[] array,int start,int end) {if(start >= end){return;}if(end - start + 1 <= 15){insertSort(array,start,end);return;}int index = middleNume(array,start,end);swap(array,start,index);int pivot = partition(array,start,end);quick(array,start,pivot-1);quick(array,pivot+1,end);}

优化

 public static void  quickSort(int[] array){quick(array,0, array.length-1);}    
private static void quick(int[] array,int start,int end) {if(start >= end){return;}if(end - start + 1 <= 15){insertSort(array,start,end);return;}int index = middleNume(array,start,end);swap(array,start,index);int pivot = partitionHoare(array,start,end);quick(array,start,pivot-1);quick(array,pivot+1,end);}private static int middleNume(int[] array, int left, int right) {int mid = (left + right)/2;if(array[left] < array[right] ){if(array[mid] < array[left]){return left;}else if(array[mid] > array[right]){return right;}else {return mid;}}else {if(array[mid] < array[right]){return right;}else if(array[mid] > array[left]){return left;}else {return mid;}}}public static void insertSort(int[] array,int left,int right){for (int i = left+1; i <= right; i++) {int tmp = array[i];int j = i - 1;for (; j >= left ; j--) {if(array[j] > tmp){array[j + 1] = array[j];}else {break;}}array[j+1] = tmp;}}

非递归的方法 

  public static void  quickSortNor(int[] array){int start = 0;int end = array.length -1;Stack<Integer> stack =new Stack<>();int pivot = partitionHoare(array,start,end);if(pivot - 1 > start){stack.push(start);stack.push(pivot-1);}if(pivot+1 < end){stack.push(pivot+1);stack.push(end);}while(!stack.empty()){end =stack.pop();start = stack.pop();pivot = partitionHoare(array,start,end);if(pivot - 1 > start){stack.push(start);stack.push(pivot-1);}if(pivot+1 < end){stack.push(pivot+1);stack.push(end);}}}private static int partitionHoare(int[] array, int left, int right) {int tmp = array[left];int i = left;while(left < right){while(left < right && array[right] >= tmp){right--;}while (left < right && array[left] <= tmp){left++;}swap(array,left,right);}swap(array,i,left);return left;}

4. 归并排序

时间复杂度:0(N*logN)

空间复杂度:0(logN)

稳定性:稳定的

排序目前为止3个稳定的排序:直接插入排序、冒泡排序、归并排序

   public static void mergeSort(int[] array){mergeSortFun(array,0,array.length-1);}public static void mergeSortFun(int[] array,int start,int end){if(start >= end){return;}int mid = (start + end)/2;mergeSortFun(array,start,mid);mergeSortFun(array,mid+1,end);//左右两边数组合并merge(array,start,mid,end);}public static void merge(int[] array,int left,int mid, int right){int s1 = left;int e1 = mid;int s2 = mid+1;int e2 = right;//两边的数组合并数组的长度int[] tmpArray = new int[right - left +1];int k = 0;while (s1 <= e1 && s2 <= e2){if(array[s1] < array[s2]){tmpArray[k++] = array[s1++];}else {tmpArray[k++] = array[s2++];}}while (s1 <= e1){tmpArray[k++] = array[s1++];}while (s2 <= e2){tmpArray[k++] = array[s2++];}for (int i = 0; i < tmpArray.length; i++) {array[left+i] = tmpArray[i];}}

 非递归

   public static void merge(int[] array,int left,int mid, int right){int s1 = left;int e1 = mid;int s2 = mid+1;int e2 = right;//两边的数组合并数组的长度int[] tmpArray = new int[right - left +1];int k = 0;while (s1 <= e1 && s2 <= e2){if(array[s1] < array[s2]){tmpArray[k++] = array[s1++];}else {tmpArray[k++] = array[s2++];}}while (s1 <= e1){tmpArray[k++] = array[s1++];}while (s2 <= e2){tmpArray[k++] = array[s2++];}for (int i = 0; i < tmpArray.length; i++) {array[left+i] = tmpArray[i];}}public static void mergeSortNor(int[] array) {//每组几个数据int gap = 1;while(gap < array.length){for (int i = 0; i < array.length; i = i + gap*2) {int left = i;int mid = left + gap -1;int right = mid + gap;if(mid >= array.length){mid = array.length - 1;}if(right >= array.length){right = array.length - 1;}merge(array,left,mid,right);}gap = gap*2;}}

5.非比较排序

 使用场景是给定一个指定的待排序的序列

    public static void countSort(int[] array){int minVal = array[0];int maxVal = array[0];for (int i = 0; i < array.length; i++){if(array[i] > maxVal){maxVal = array[i];}if(array[i] < minVal){minVal = array[i];}}int len = maxVal - minVal + 1;int[] count = new int[len];for (int i = 0; i < array.length; i++) {count[array[i]-minVal]++;}int index = 0;for (int i = 0; i < array.length; i++) {while(count[0] > 0){array[index] = i + minVal;index++;count[i]--;}}}

 海量数据的排序问题


外部排序:排序过程需要在磁盘等外部存储进行的排序
前提:内存只有 1G,需要排序的数据有 100G
因为内存中因为无法把所有数据全部放下,所以需要外部排序,而归并排序是最常用的外部排序
1. 先把文件切分成 200 份,每个 512 M
2. 分别对 512 M 排序,因为内存已经可以放的下,所以任意排序方式都可以
3. 进行 2路归并,同时对 200 份有序文件做归并过程,最终结果就有序了

 记录当前电脑的时间

long startTime =System.currentTimeMillis();

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

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

相关文章

计算机网络chapter1——家庭作业

文章目录 复习题1.1节&#xff08;1&#xff09; “主机”和“端系统”之间有何不同&#xff1f;列举几种不同类型的端系统。web服务器是一种端系统吗&#xff1f;&#xff08;2&#xff09;协议一词常用来用来描述外交关系&#xff0c;维基百科是如何描述外交关系的&#xff1…

mac虚拟机软件哪个好 mac虚拟机怎么安装Windows 苹果Mac电脑上受欢迎的主流虚拟机PK Parallels Desktop和VM

什么是苹果虚拟机&#xff1f; 苹果虚拟机是一种软件工具&#xff0c;它允许在非苹果硬件上运行苹果操作系统&#xff08;如ios&#xff09;。通过使用虚拟机&#xff0c;您可以在Windows PC或Linux上体验和使用苹果的操作系统&#xff0c;而无需购买苹果硬件。 如何使用苹果虚…

CSDN如何在个人主页开启自定义模块|微信公众号

目前只有下面三种身份才具有这个功能。 VIP博客专家企业博客 栏目内容不知道怎么写HTML的&#xff0c;可以联系我帮你添加

Maven入门:1.简介与环境搭建

一.简介与环境搭建 1.Maven&#xff1a;用于自动化构建项目&#xff08;按照企业主流模板构建完善的项目结构&#xff09;和管理项目依赖&#xff08;依赖就是项目的jar包&#xff0c;通过配置的方式进行添加和管理&#xff0c;自动下载和导入&#xff09;的工具。即更加方便构…

C 408—《数据结构》图、查找、排序专题考点(含解析)

目录 Δ前言 六、图 6.1 图的基本概念 6.2 图的存储及基本操作 6.3 图的遍历 6.4 图的应用 七、查找 7.2 顺序查找和折半查找 7.3 树型查找 7.4 B树和B树 7.5 散列表 八、排序 8.2 插入排序 8.3 交换排序 8.4 选择排序 8.5 归并排序和基数排序 8.6 各种内部排序算法的比较及…

表格中斜线的处理

此处的斜线,不是用表格写的,但是也适用于表格,只是需要更改表格的样式,可以 按照如下处理,即可 呈现的效果:如图所示 template部分: <div class"header_detail custom"><div class"right">节次</div><div class"left">…

C/C++实现高性能并行计算——1.pthreads并行编程(中)

系列文章目录 pthreads并行编程(上)pthreads并行编程(中)pthreads并行编程(下)使用OpenMP进行共享内存编程 文章目录 系列文章目录前言一、临界区1.1 pi值估计的例子1.2 找到问题竞争条件临界区 二、忙等待三、互斥量3.1 定义和初始化互斥锁3.2 销毁。3.3 获得临界区的访问权&…

windows11安装nginx

1.解压nginx安装包到没有中文的目录 2.双击运行nginx.exe 3.任务管理器查看是否有nginx进程 4.任务管理器->性能->资源监视器 5.网络->侦听端口&#xff0c;查看nginx侦听的端口&#xff0c;这里是90端口

大连宇都环境 | 成都5月水科技大会暨技术装备成果展览会

中华环保联合会水环境治理专业委员会 秘书处 王小雅 13718793867 —— 展位号&#xff1a;A09 —— 一、企业介绍 大连宇都环境成立于2002年&#xff0c;公司20年 MBBR填料产品及工艺技术&#xff0c;&#xff0c;构建了研发、制造、设计、工程、运营链式服务能力&#xff…

数据赋能(73)——数据要素:特征

生产要素中的数据要素具有一系列基本特征&#xff0c;这些特征使得数据在现代经济活动中发挥着越来越重要的作用。数据要素的主要特征如下图所示。 数据已经成为关键的生产要素&#xff0c;数据要素的基本特征可以概括为&#xff1a;虚拟性、非消耗性、非稀缺性、非均质性、排他…

selinux 基础知识

目录 概念 作用 SELinux与传统的权限区别 SELinux工作原理 名词解释 主体&#xff08;Subject&#xff09; 目标&#xff08;Object&#xff09; 策略&#xff08;Policy&#xff09; 安全上下文&#xff08;Security Context&#xff09; 文件安全上下文查看 先启用…

如何解决网络应用运行中的审核问题【系列研究预告】

目前互联网是非常发达的&#xff0c;但是随着技术的发展&#xff0c;有些问题逐渐变得严重。对于一般企业而言&#xff0c;一个比较重要的问题就是审核准确性和成本问题。 比如知乎的审判官&#xff0c;我本人是最早的一批审判官&#xff0c;然而多年下来的经历却很让人感到无…

数据结构—C语言实现双向链表

目录 1.双向带头循环链表 2.自定义头文件&#xff1a; 3.List.cpp 文件 3.1 newnode()函数讲解 3.2 init() 函数 初始化 3.3 pushback()函数 尾插 3.4 pushfront()函数 头插 3.5 popback() 尾删 3.6 popfront() 函数 头删 3.7 insert()函数 在pos之后插入 3.8 popbac…

uniapp 对接 Apple 登录

由于苹果要求App使用第三方登录必须要求接入Apple登录 不然审核不过 所以&#xff1a; 一、勾选苹果登录 二、 设置AppId Sign In Apple 设置完成重新生成描述文件 &#xff01;&#xff01;&#xff01;&#xff01;证书没关系 示例代码&#xff1a; async appleLogin…

Delta lake with Java--将数据保存到Minio

今天看了之前发的文章&#xff0c;居然有1条评论&#xff0c;看到我写的东西还是有点用。 今天要解决的问题是如何将 Delta产生的数据保存到Minio里面。 1、安装Minio&#xff0c;去官网下载最新版本的Minio&#xff0c;进入下载目录&#xff0c;运行如下命令&#xff0c;曾经…

Co-assistant Networks for Label Correction论文速读

文章目录 Co-assistant Networks for Label Correction摘要方法Noise DetectorNoise Cleaner损失函数 实验结果 Co-assistant Networks for Label Correction 摘要 问题描述&#xff1a; 描述医学图像数据集中存在损坏标签的问题。强调损坏标签对深度神经网络性能的影响。 提…

SpringBoot指标监控

一.SpringBoot指标监控_添加Actuator功能 Spring Boot Actuator可以帮助程序员监控和管理SpringBoot应用&#xff0c;比如健康检查、内存使用情况统计、线程使用情况统计等。我 们在SpringBoot项目中添加Actuator功能&#xff0c;即可使用Actuator监控 项目&#xff0c;用法如…

使用YALMIP定义LMI,SEDUMI求解矩阵方程

YALMIP&#xff08;Yet Another MATLAB Package for Modeling and Optimization&#xff09;是一个MATLAB工具箱&#xff0c;用于定义和求解优化问题&#xff0c;包括线性矩阵不等式&#xff08;LMI&#xff09;问题。SEDUMI是一个用于求解LMI问题的求解器&#xff0c;它可以与…

Vitis HLS 学习笔记--S_AXILITE 寄存器及驱动

目录 1. 简介 2. S_AXILITE Registers 寄存器详解 2.1 “隐式”优势 2.2 驱动程序文件 2.3 硬件头文件 2.4 硬件头文件中 SC/COR/TOW/COH 的解释 2.5 驱动控制过程 3. 总结 1. 简介 回顾此博文《Vitis HLS 学习笔记--Syn Report解读&#xff08;1&#xff09;-CSDN博…

瘦身秘籍:如何使用 PyInstaller 打造超小型 Python 可执行文件

你是否曾经尝试过将你的 Python 程序打包成一个可执行文件&#xff0c;却发现生成的文件大得惊人&#xff1f;别担心&#xff0c;本文将教你如何使用 PyInstaller 尽可能减小生成的 onefile 大小&#xff0c;让你的程序轻盈如风&#xff01; 1. 使用虚拟环境 首先&#xff0c…