汇总

序号 排序算法 平均时间 最好情况 最差情况 稳定度 额外空间 备注 相对时间
1 冒泡算法 O(n2) O(n) O(n2) 稳定 O(1) n 越小越好 182 ms
2 选择算法 O(n2) O(n2) O(n2) 不稳定 O(1) n 越小越好 53 ms
3 插入算法 O(n2) O(n) O(n2) 稳定 O(1) 大部分排序好时好 16 ms
4 快速算法 O(nlog2n) O(nlog2n) O(n2) 不稳定 O(nlog2n) n 大时好 719 ms
5 归并算法 O(nlog2n) O(nlog2n) O(nlog2n) 稳定 O(n) n 大时好 550 ms
6 希尔算法 O(nlog2n) O(n) O(n2) 不稳定 O(1) 197 ms/4 ms
7 堆排序 O(nlog2n) O(nlog2n) O(nlog2n) 不稳定 O(1) n 大时好 3 ms
8 计数排序 O(n+k) O(n+k) O(n+k) 稳定 O(n+k) k 是桶的数量 2 ms
9 桶排序 O(n+k) O(n) O(n2) 稳定 O(n+k) 11 ms
10 基数排序 O(n*k) O(n*k) O(n*k) 稳定 O(n+k) 4 ms
11 优先队列 不稳定 O(n) 9 ms
12 Java API O(1) 4 ms

1. 冒泡排序

每轮循环确定最值;

public void bubbleSort(int[] nums){
int temp;
boolean isSort = false; //优化,发现排序好就退出
for (int i = 0; i < nums.length-1; i++) {
for (int j = 0; j < nums.length-1-i; j++) { //每次排序后能确定较大值
if(nums[j] > nums[j+1]){
isSort = true;
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
if(!isSort){
return;
} else {
isSort = false;
}
}
}

2. 选择排序

每次选出最值,再交换到边上;

public void selectSort(int[] nums){
for (int i = 0; i < nums.length-1; i++) {
int index = i;
int minNum = nums[i];
for (int j = i+1; j < nums.length; j++) {
if(nums[j] < minNum){
minNum = nums[j];
index = j;
}
}
if(index != i){
nums[index] = nums[i];
nums[i] = minNum;
}
}
}

3. 插入排序

对循环的每个数找到属于自己的位置插入;

public void insertionSort(int[] nums){
for (int i = 1; i < nums.length; i++) {
int j = i;
int insertNum = nums[i];
while(j-1 >= 0 && nums[j-1] > insertNum){
nums[j] = nums[j-1];
j--;
}
nums[j] = insertNum;
}
}

4. 快速排序

选一个基本值,小于它的放一边,大于它的放另一边;

public void quickSortDfs(int[] nums, int left, int right){
if(left > right){
return;
}
int l = left;
int r = right;
int baseNum = nums[left];
while(l < r){
//必须右边先走
while(nums[r] >= baseNum && l < r){
r--;
}
while(nums[l] <= baseNum && l < r){
l++;
}
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
nums[left] = nums[l];
nums[l] = baseNum;
quickSortDfs(nums, left, r-1);
quickSortDfs(nums, l+1, right);
}

5. 归并排序

分治算法;

//归
public void mergeSortDfs(int[] nums, int l, int r){
if(l >= r){
return;
}
int m = (l+r)/2;
mergeSortDfs(nums, l, m);
mergeSortDfs(nums, m+1, r);
merge(nums, l, m, r);
}
//并
private void merge(int[] nums, int left, int mid, int right){
int[] temp = new int[right-left+1];
int l = left;
int m = mid+1;
int i = 0;
while(l <= mid && m <= right){
if(nums[l] < nums[m]){
temp[i++] = nums[l++];
} else {
temp[i++] = nums[m++];
}
}
while(l <= mid){
temp[i++] = nums[l++];
}
while(m <= right){
temp[i++] = nums[m++];
}
System.arraycopy(temp, 0, nums, left, temp.length);
}

6. 希尔排序

引入步长减少数字交换次数提高效率;

6.1 希尔-冒泡排序(慢)

public void shellBubbleSort(int[] nums){
for (int step = nums.length/2; step > 0 ; step /= 2) {
for (int i = step; i < nums.length; i++) {
for (int j = i-step; j >= 0; j -= step) {
if(nums[j] > nums[j+step]){
int temp = nums[j];
nums[j] = nums[j+step];
nums[j+step] = temp;
}
}
}
}
}

6.2 希尔-插入排序(快)

public void shellInsertSort(int[] nums){
for (int step = nums.length/2; step > 0; step /= 2) {
for (int i = step; i < nums.length; i++) {
int j = i;
int insertNum = nums[i];
while(j-step >= 0 && nums[j-step] > insertNum){
nums[j] = nums[j-step];
j-=step;
}
nums[j] = insertNum;
}
}
}

7. 堆排序

大顶堆实现升序,每次将最大值移到堆的最后一个位置上;

public void heapSort2(int[] nums) {
for(int i = nums.length/2-1; i >= 0; i--){
sift(nums, i, nums.length);
}
for (int i = nums.length-1; i > 0; i--) {
int temp = nums[0];
nums[0] = nums[i];
nums[i] = temp;
sift(nums, 0, i);
}
}
private void sift(int[] nums, int parent, int len) {
int value = nums[parent];
for (int child = 2*parent +1; child < len; child = child*2 +1) {
if(child+1 < len && nums[child+1] > nums[child]){
child++;
}
if(nums[child] > value){
nums[parent] = nums[child];
parent = child;
} else {
break;
}
}
nums[parent] = value;
}

8. 计数排序

按顺序统计每个数出现次数;

public void countSort(int[] nums){
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int num : nums){
max = Math.max(max, num);
min = Math.min(min, num);
} int[] countMap = new int[max-min+1];
for(int num : nums){
countMap[num-min]++;
}
int i = 0;
int j = 0;
while(i < nums.length && j < countMap.length){
if(countMap[j] > 0){
nums[i] = j+min;
i++;
countMap[j]--;
} else {
j++;
}
}
}

9. 桶排序

类似计数排序,不同点在于统计的是某个区间(桶)里的数;

public void bucketSort(int[] nums){
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int num : nums){
max = Math.max(max, num);
min = Math.min(min, num);
}
int bucketCount = (max-min)/nums.length+1;
List<List<Integer>> bucketList = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
bucketList.add(new ArrayList<>());
} for(int num : nums){
int index = (num-min)/nums.length;
bucketList.get(index).add(num);
}
for(List<Integer> bucket : bucketList){
Collections.sort(bucket);
} int j = 0;
for(List<Integer> bucket : bucketList){
for(int num : bucket){
nums[j] = num;
j++;
}
}
}

10. 基数排序

按个、十、百位依次归类排序;

public  void radixSort(int[] nums){
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int num : nums) {
min = Math.min(min, num);
max = Math.max(max, num);
}
for (int i = 0; i < nums.length; i++) {
nums[i] -= min;
}
max -= min;
int maxLen = (max+"").length(); int[][] bucket = new int[nums.length][10];
int[] bucketCount = new int[10]; for (int i = 0, n = 1; i < maxLen; i++, n*=10) {
for (int num : nums) {
int digitVal = num / n % 10;
bucket[bucketCount[digitVal]][digitVal] = num;
bucketCount[digitVal]++;
}
int index = 0;
for (int j = 0; j < bucketCount.length; j++) {
if(bucketCount[j] > 0){
for (int k = 0; k < bucketCount[j]; k++) {
nums[index] = bucket[k][j];
index++;
}
}
bucketCount[j] = 0;
}
}
for (int i = 0; i < nums.length; i++) {
nums[i] += min;
}
}

11. 使用集合或 API

11.1 优先队列

public void priorityQueueSort(int[] nums){
PriorityQueue<Integer> queue = new PriorityQueue<>();
for(int num : nums){
queue.offer(num);
}
for (int i = 0; i < nums.length; i++) {
nums[i] = queue.poll();
}
}

11.2 Java API

public void arraysApiSort(int[] nums){
Arrays.sort(nums);
}

最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!

算法 | Java 常见排序算法(纯代码)的更多相关文章

  1. Java常见排序算法之归并排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  2. Java常见排序算法之Shell排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  3. Java常见排序算法之折半插入排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  4. Java常见排序算法之直接插入排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  5. Java常见排序算法之快速排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  6. Java常见排序算法之冒泡排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  7. Java常见排序算法之堆排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  8. Java常见排序算法之直接选择排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  9. java常见排序算法

    今天去面试的时候又考了排序算法,排序这个东西,你以为你懂了,但是真正去写的时候才会发现好多细节自己都模棱两可,我写着写着就全都乱了,回来之后赶紧重新写一遍. (1)冒泡排序 public void b ...

随机推荐

  1. python小白记录三——pycharm+selenium搭建环境之 no module named 'selenium'异常解决

    在pycharm上搭建python+selenium自动化测试环境时,遇到一个很坑的问题:no moduel named 'selenium' 如下图: 1.查看你的python是否正确安装了sele ...

  2. 面向过程编程+模块&导入

    面向过程编程+模块&导入 一.面向过程编程(理论+简单代码) 面向过程编程就好比在设计一条产品流水线 首先我们来认识下,什么是面向过程?如果咬文嚼字的话可以这样来理解,面向过程就是面向解决问题 ...

  3. Haar小波分析

    一 尺度函数与小波函数 基本尺度函数定义为:,对其向右平移任意 k 个单位,构成函数族 , 该函数族在 空间中正交,证明如下: 1 : 2 当 m 不等于 k 时, 函数族  构成一组正交基,并形成  ...

  4. PHP7.x环境下安装redis扩展

    注:以下介绍的安装方式为PHP的安装路径为/usr/local/php,如果你的服务器上PHP的安装目录不一致请按实际情况处理. 首先下载PHP7的redis扩展 wget https://githu ...

  5. libc++abi.dylib: terminating with uncaught exception of type NSException

    这是微信sdk注册时候报的错误 解决方法 选择Build Setting,在"Other Linker Flags"中加入"-Objc -all_load"

  6. k8s-ingress增加跨域问题

    第一种: kubectl get ingresses. -n rrzhibo-admin test-rrzb-apiadmin-gateway-http-ingress -o yaml apiVers ...

  7. const 和指针之间的姻缘

    const和指针到底有何姻缘呢? char const *p = NULL; //char const 和 const char 是一样的,p 是一个指向常整型的指针变量 ,指针变量的值不能改变 ch ...

  8. jmeter压测tcp协议接口:java.net.SocketException: Software caused connection abort: socket write error

    tcp接口,试压过程中,部分请求报如下错误: java.net.SocketException: Software caused connection abort: socket write erro ...

  9. schtasks

    schtasks create    创建新的计划任务. 语法 schtasks /create /tn TaskName /tr TaskRun /sc schedule [/mo modifier ...

  10. Windows server 2012安装vm-tools遇到的问题

    Windows server 2012安装VM tools异常解决办法 在VMWare虚拟机上安装Windows Server 2012之 后安装VMWare Tools时报如下错误信息: 问题:缺少 ...