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:注意无法使用构 ...
随机推荐
- java集合-HashMap源码解析
HashMap 键值对集合 实现原理: HashMap 是基于数组 + 链表实现的. 通过hash值计算 数组索引,将键值对存到该数组中. 如果多个元素hash值相同,通过链表关联,再头部插入新添加的 ...
- Python----多项式回归
多项式线性回归 1.多项式线性方程: 与多元线性回归相比,它只有一个自变量,但有不同次方数. 2.举例: import numpy as np import matplotlib.pyplot as ...
- BSScrollViewEdgePop
https://blog.csdn.net/qq_17190231/article/details/84201956 2018年11月18日 16:52:39 FreeBaiShun 阅读数:66 标 ...
- Python3.7源码在windows(VS2015)下的编译和安装
Python3.7源码在windows(VS2015)下的编译和安装 下载官方源码,使用vs2015(WIN10SDK),最python3.7.0的源码进行编译,编译出不同的版本(release,de ...
- poj-1904(强连通缩点)
题意:有n个王子,每个王子都有k个喜欢的女生,王子挑选喜欢的女生匹配,然后再给你n个王子最开始就定好的匹配,每个王子输出能够结合且不影响其他王子的女生匹配 解题思路:强连通缩点,每个王子与其喜欢的女生 ...
- odoo Model字段的参数
odoo Model字段的参数 class Field(object): """ The field descriptor contains the field defi ...
- loadrunner断言多结果返回
有这么一个场景,接口返回的多个状态都是正常的,那么在压测的时候,断言就需要多 init里面执行登录,根据返回获取到tokenId action中,执行登录后的操作,获取响应返回的状态,把正确的状态个数 ...
- YUI Compressor
简介 根据雅虎卓越性能团队的说法,40%到60%的雅虎用户拥有空闲缓存体验,所有页面浏览量中约有20%是使用空缓存完成的(请参阅Tenni Theurer在YUIBlog上的这篇文章)有关浏览器缓存使 ...
- EOF输入
EOF是一个计算机术语,为End Of File的缩写,在操作系统中表示资料源无更多的资料可读取.资料源通常称为档案或串流.通常在文本的最后存在此字符表示资料结束.是int类型的宏定义,它扩展为负整数 ...
- css解决图片拉伸问题
在实际场景中,我们经常会遇到图片大小固定的需求,但是由于原始图片大小,比例不一样,不同图片以相同的大小展示会参差不齐.解决方法就是object-fit或者background-size属性.他们的区别 ...