JAVA学习笔记(4)—— 排序算法
排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。
排序算法大体可分为两种:
一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。
另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等
稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。
1、冒泡排序
* 冒泡排序
* 冒泡排序是一种极其简单的排序算法,也是我所学的第一个排序算法。它重复地走访过要排序的元素,依次比较相邻两个元素
* ,如果他们的顺序错误就把他们调换过来,直到没有元素再需要交换,排序完成。这个算法的名字由来是因为越小(或越大)的
* 元素会经由交换慢慢“浮”到数列的顶端。
*
* 冒泡排序算法的运作如下:
* (1)比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
* (2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
* (3)针对所有的元素重复以上的步骤,除了最后一个。
* (4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public class BubbleSort {
public static int[] sort(int[] arr){
int temp=0;
int n=arr.length;
for(int i=1;i<n;i++){
for(int j=0;j<n-i;j++){
if(arr[j]>arr[j+1]){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
//输出每次排序完成后的数组
PrintArray.printArray(arr);
System.out.println();
}
return arr;
}
}
2、插入排序
插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,
* 需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
*
* 具体算法描述如下:
* 从第一个元素开始,该元素可以认为已经被排
* 取出下一个元素,在已经排序的元素序列中从后向前扫描
* 如果该元素(已排序)大于新元素,将该元素移到下一位
* 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
* 将新元素插入到该位置后
* 重复步骤2~5*/
public class InsertSort { public static int[] sort(int[] arr){
int n=arr.length;
for(int i=1;i<n;i++){
int num=arr[i];
//当前位置前一个位置
int j=i-1;
while(j>=0 && arr[j]>num){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=num;
PrintArray.printArray(arr);
System.out.println();
}
return arr;
}
}
3、希尔排序
/*希尔排序,也叫递减增量排序,是插入排序的一种更高效的改进版本。希尔排序是不稳定的排序算法。
* 希尔排序是基于插入排序的以下两点性质而提出改进方法的
* 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
* 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位
* 希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。
* 然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
* 假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n^2)的排序(冒泡排序或直接插入排序),可能会进行n次的
* 比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。
* */
public static void shellSort(int[] arr){ for(int r=arr.length/2;r>=1;r=r/2){
int temp;
int j = 0;
for(int i=r;i<arr.length;i=i+1){
temp=arr[i];
j=i-r;
while(j>=0&&temp<arr[j]){
arr[j+r]=arr[j];
j=j-r;
}
arr[j+r]=temp;
}
} for(int a:arr)
System.out.print(a+" ");
System.out.println();
}
4、选择排序
* 选择排序也是一种简单直观的排序算法。它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列
* 的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此
* 类推,直到所有元素均排序完毕。
*
* 注意选择排序与冒泡排序的区别:
* 冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍
* 历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置*/
public static int[] sort(int[] arr){
int n=arr.length;
for(int i=0;i<n-1;i++){
int minNum=i;
for(int j=i+1;j<n;j++){
if(arr[minNum]>arr[j]){
minNum=j;
}
}
int temp=arr[i];
arr[i]=arr[minNum];
arr[minNum]=temp; }
return arr;
}
5、快速排序
*快速排序,顾名思义,是一种速度快,效率高的排序算法。
快排原理:
在要排的数(比如数组A)中选择一个中心值key(比如A[0]),通过一趟排序将数组A分成两部分,
其中以key为中心,key右边都比key大,key左边的都key小,然后对这两部分分别重复这个过程,
直到整个有序。
整个快排的过程就简化为了一趟排序的过程,然后递归调用就行了。
一趟排序的方法:
1,定义i=0,j=A.lenght-1,i为第一个数的下标,j为最后一个数下标
2,从数组的最后一个数Aj从右往左找,找到第一小于key的数,记为Aj;
3,从数组的第一个数Ai 从左往右找,找到第一个大于key的数,记为Ai;
4,交换Ai 和Aj
5,重复这个过程,直到 i=j
6,调整key的位置,把A[i] 和key交换
public static int[] sort(int[] arr,int l,int r){
int size=arr.length;
if(l<r){
int i=l,j=r,x=arr[l];
while(i<j){
while(i<j&&arr[j]>x)
j--;
if(i<j)
arr[i++]=arr[j];
while(i<j&&arr[i]<x)
i++;
if(i<j)
arr[j--]=arr[i];
}
arr[i]=x;
sort(arr, l, i-1);
sort(arr, i+1, r);
}
return arr;
}
JAVA学习笔记(4)—— 排序算法的更多相关文章
- STL学习笔记(排序算法)
STL提供了好几种算法对区间内的元素排序.出来完全排序外,还支持局部排序. 对所有元素排序 void sort(RandomAccessIterator beg,RandomAccessIterato ...
- TSPL学习笔记(3):排序算法练习
快速排序 快排的详细介绍见,简单的说就是取输入序列中的首元素m,然后将除首元素m以外的其它元素分成两组,小于等于m的一组和大于m的一组.将3组元素组合成输入队列:小于等于m + m + 大于m. 下面 ...
- js学习笔记之排序算法的原理及代码
冒泡排序 比较任何两个相邻的项,如果第一个比第二个大,则交换它们 重复这样的操作,直到排序完成,具体代码如下: let arr = [67,23,11,89,45,76,56,99] function ...
- Java学习笔记——排序算法之快速排序
会当凌绝顶,一览众山小. --望岳 如果说有哪个排序算法不能不会,那就是快速排序(Quick Sort)了 快速排序简单而高效,是最适合学习的进阶排序算法. 直接上代码: public class Q ...
- Java基础复习笔记基本排序算法
Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- java学习笔记13--比较器(Comparable、Comparator)
java学习笔记13--比较器(Comparable.Comparator) 分类: JAVA 2013-05-20 23:20 3296人阅读 评论(0) 收藏 举报 Comparable接口的作用 ...
- java学习笔记11--集合总结
java学习笔记系列: java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Ob ...
- 20145330第八周《Java学习笔记》
20145330第八周<Java学习笔记> 第十五章 通用API 通用API 日志:日志对信息安全意义重大,审计.取证.入侵检验等都会用到日志信息 日志API Logger:注意无法使用构 ...
随机推荐
- Robust PCA via Outlier Pursuit
目录 引 主要结果 定理1 定理2 理论证明 构造Oracle Problem 算法 Xu H, Caramanis C, Sanghavi S, et al. Robust PCA via Outl ...
- 数据库常用的事务隔离级别和原理?&&mysql-Innodb事务隔离级别-repeatable read详解
转载地址:https://baijiahao.baidu.com/s?id=1611918898724887602&wfr=spider&for=pc https://blog.csd ...
- [转帖]Zoom
Zoom美国上市:华裔创始人为大股东 创业想法来自“异地恋” https://baijiahao.baidu.com/s?id=1631166070308020680&wfr=spider&a ...
- vue中watch检测到不到对象属性的变化的解决方法
watch: { option: { handler(newVal) { console.log(newVal); }, deep: true, immediate: true } }, 需要深层wa ...
- sql中检查时间是否重叠
先画一个时间轴,方便理解. 设新的时间块,开始时间为@BeginDate,结束时间为@EndDate.数据库中的数据为BeginDate和EndDate 这样可以直观的看出来,新的时间块插入进来,只需 ...
- Spring Boot 2.x 编写 RESTful API (一) RESTful API 介绍 & RestController
用Spring Boot编写RESTful API 学习笔记 RESTful API 介绍 REST 是 Representational State Transfer 的缩写 所有的东西都是资源,所 ...
- [ffmpeg] AVOption
在ffmpeg中,常使用AVOption的API来进行参数设置.AVOption的API主要分为设置参数以及提取参数两种,无论是哪一种API都主要分为两大步骤: 寻找出参数所在的内存位置. 如果是设置 ...
- BZOJ5019[Snoi2017]遗失的答案——FWT+状压DP
题目描述 小皮球在计算出答案之后,买了一堆皮肤,他心里很开心,但是一不小心,就忘记自己买了哪些皮肤了.==|||万 幸的是,他还记得他把所有皮肤按照1-N来编号,他买来的那些皮肤的编号(他至少买了一款 ...
- 【BZOJ2721】樱花(数论)
[BZOJ2721]樱花(数论) 题面 BZOJ 题解 先化简一下式子,得到:\(\displaystyle n!(x+y)=xy\),不难从这个式子中得到\(x,y\gt n!\). 然后通过\(x ...
- 【dp】P2642 双子序列最大和
题目描述 给定一个长度为n的整数序列,要求从中选出两个连续子序列,使得这两个连续子序列的序列和之和最大,最终只需输出最大和.一个连续子序列的和为该子序列中所有数之和.每个连续子序列的最小长度为1,并且 ...