八大排序算法

1、冒泡排序

思想:

(1)相邻两个元素依次比较,保证右边元素大于左边(小于则交换位置),一轮结束后保证最后一个元素一定是最大的元素

(2)对剩下n-1个元素再次执行(1)

(3)第n-1轮执行后序列排序完成

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
冒泡 O(n) O(n^2) O(n^2) O(1) 数据量小,有序 稳定

实现代码:

public static void bubbleSort(int data[]) {boolean didSwap;for (int i = 0; i < data.length - 1; i++) {didSwap = false;for (int j = 0; j < data.length - i - 1; j++) {if (data[j + 1] < data[j] ) {//加等于则不稳定int temp = data[j + 1];data[j + 1] = data[j];data[j] = temp;didSwap = true;}}if (!didSwap) {return;}}}

2、 选择排序

思想:

(1)从序列中选出最大元素

(2)如果最大元素不是在最后一位,将其互换位置

(3)对剩下的n -1 个元素执行(1)(2)

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
直接选择 O(n^2) O(n^2) O(n^2) O(1) 数据量小 稳定

注:选择排序稳定性跟代码实现方式有关,这种写法为稳定

代码:

public static int[] selectionSort(int data[]){for (int i = 0; i < data.length -1; i++) {int maxIndex = 0;for (int j = 0; j < data.length - i; j++) {if (data[j] >= data [maxIndex]) {//加等于稳定maxIndex = j;}}if (maxIndex != data.length - i -1) {int temp = data[data.length - i -1];data[data.length - i -1] = data[maxIndex];data[maxIndex] = temp;}}return data;
}

3、直接插入排序

思想:

(1)将第i元素与排好序的n个数的序列做比较(默认第一个元素为有序),如果有序序列中有元素比第i个位置的元素大,互换位置,直至排好序的所有元素与第i个位置的元素比较过则前n+1个元素有序

(2)重复(1), 直至整个序列有序

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
直接插入 O(n) O(n^2) O(n^2) O(1) 数据量小,有序 稳定

代码:

public static int[] straightInsertionSort(int data[]) {for (int i = 1; i < data.length ; i++) {for (int j = 0; j < i; j++) {if (data[j] > data [i]) {int temp = data[j];data[j] = data[i];data[i]= temp;}}}return data;
}

4、希尔排序

思想:

(1)将元素通过步长分组,组内用直接插入排序使其有序

(2)随着步长逐渐减小,每个分组的记录数越来越多,当步长减为1时,所有记录合成一组,所有记录有序

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
希尔排序 O(n^1.3) O(n^2) O(n^2) O(1) 数据量大 不稳定

代码:

public static int[] shellSort(int data[]) {for (int gap = data.length/2; gap > 0; gap /=2) {//保证初始前面只有一个元素使其有序 然后每次插入和之前有序序列比较for (int i = gap; i < data.length; i++) {straightInsertionSort(data,i,gap);}}return data;
}
​
private static void straightInsertionSort(int[] data, int index, int gap) {for (int  j = index%gap; j <= index - gap; j += gap) {//同一组的和之前有序的元素比较交换if (data[index] < data [j]) {int temp = data[index];data[index] = data[j];data[j] = temp;}}
}

5、快速排序

思想:

(1)单次排序时,选择第一个元素为基准数,i,j分别指向第一个元素和最后一个元素,j先向前扫描,若data[j] 大于等于基准数,则继续往前扫描,当data[j]小于基准数时,基准数和data[j] 互换位置,i向后扫描,若data[i] 小于等于基准数,则继续往前扫描,当data[i]大于基准数时,基准数和data[i]] 互换位置,然后j继续向前扫描,i,j交替扫描,直至i == j,则一次排序完成

(2)一次排序使基准数左边小于基准数,右边大于基准数

(3)对于基准数左边和右边元素重复(1),(2)

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
快速排序 O(nlog2n) O(n^2) O(nlog2n) O(nlog2n) 数据量大 不稳定
public static void quickSort(int data[],int low,int high) {if (low < high) {int middleIndex = getMiddleIndex(data,low,high);quickSort(data,low,middleIndex - 1);quickSort(data,middleIndex + 1,high);}
}
​
private static int getMiddleIndex(int[] data, int low, int high) {int key = data[low];while (low < high) {while (data[high] > key && low < high){high --;}data[low] = data[high];while (data[low] <= key && low < high) {low ++;}data[high] = data[low];}data[low] = key;return low;
}

6、堆排序

思想:

(1)将无序序列构造为大顶或者小顶堆,每次取出堆顶元素,将堆尾元素放在堆顶,再次调整为大顶堆或者小顶堆,直至堆只剩最后一个元素

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
堆排序 O(nlog2n) O(nlog2n) O(nlog2n) O(1) 数据量大 不稳定

代码:

public static void heapSort(int data[]) {//建堆//i 指向最后一个非叶子节点for (int i = data.length/2 - 1; i >= 0; i --) {adjustHeap(data,i,data.length);}for (int k = data.length -1; k > 0; k--) {//把最大元素放到堆尾,此时只需调整根节点swap(data,0,k);adjustHeap(data,0,k);}
}
​//每个非叶子节点都要调整堆使之成为大顶堆,并循环调整所有子树
private static void adjustHeap(int[] data, int i, int length) {for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {//判断右子节点是否存在,j 指向子节点中较大的if (j + 1 < length && data[j] < data[j + 1]) {j++;}if (data[j] > data[i]) {swap(data,i,j);//循环检查子树 只调整结构改变的i = j;} else {break;}}
}
​
private static void swap (int data[],int i,int j) {int temp = data[i];data[i] = data[j];data[j] = temp;
}

7、归并排序

思想:

利用分治思想递归求解,先分解成有序序列(每组只剩一个元素),然后每个有序序列合并,直至整个序列有序

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
归并排序 O(nlog2n) O(nlog2n) O(nlog2n) O(n) 数据量大 稳定

代码:

public static void mergeSort (int data[],int left,int right,int temp[]) {if (left < right) {int mid = (left + right)/2;mergeSort(data,left,mid ,temp);mergeSort(data,mid+1,right,temp);merge(data,left,right,mid,temp);}
}
​
private static void merge(int[] data, int left, int right, int mid, int[] temp) {int i = left;int j = mid + 1;int k = left;while (i <= mid && j <= right) {temp[k++] = data[i] <= data[j] ? data[i++]:data[j++];}if (i > mid){while (k <= right) {temp[k++] = data[j++];}}if (j > right){while (k <= right) {temp[k++] = data[i++];}}for (int m = left; m <= right; m++) {data[m] = temp[m];}
}

8、基数排序

思想:

从个位开始将排序的元素按个位的值放入0~9编号的桶中,再将得到的子序列按十位的值放入桶中,一直到最高位为止

算法 最好复杂度 最差复杂度 平均复杂度 空间复杂度 适用场景 稳定性
基数排序 O(d*(n+r)) O(d*(n+r)) O(d*(n+r)) O(n+r) 数据量大 稳定

其中,d 为位数(代码中为count),r 为基数(10),n 为原数组个数(data.length)。

代码:

 public static void radixSort(int data[]){int places = getMaxPlaces(data);//最大数的位数int bucket[][] = new int [10][data.length]; //十个桶int bucketCount[] = new int[10];//每个桶数据量for (int i = 0; i < places; i++) {putBucket(data,i,bucketCount,bucket);getBucket(data,bucketCount,bucket);}}
​private static void getBucket(int[] data, int[] bucketCount, int[][] bucket) {int k = 0;for (int i = 0; i < 10; i++) {for (int j = 0; j < bucketCount[i]; j++) {data[k++] = bucket[i][j];}bucketCount[i] = 0;}}
​//按第i位入桶private static void putBucket(int[] data,int i,int bucketCount[],int bucket[][]) {int index = 0;for (int num : data) {index = (int)(num/Math.pow(10,i))%10;bucket[index][bucketCount[index]] = num;bucketCount[index]++;}}
​private static int getMaxPlaces(int[] data) {int max = data[0];for (int i = 1; i < data.length; i++) {if (data[i] > max){max = data[i];}}int count = 0;//取最大值的位数while (max > 0) {max = max/10;count ++;}return count;}

八大排序(java版)相关推荐

  1. 八大排序:Java实现八大排序及算法复杂度分析

    目录 QUESTION:八大排序:Java实现八大排序及算法复杂度分析 ANSWER: 一:冒泡排序 1.算法分析 2.时间复杂度分析 3.代码 二:选择排序 1.算法分析 2.时间复杂度分析 3.代 ...

  2. 算法练习5---快速排序Java版

    基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成 ...

  3. 八大排序(JAVA)

    文章目录 直接插入排序 希尔排序 选择排序 形式一: 形式二: 堆排序 冒泡排序 快速排序 Hoare 时间复杂度分析 注意点: 快排优化 挖坑法 前后指针法 三数取中法 递归到小区间 递归版本的优化 ...

  4. 八大排序(Java完整版)

    关于八大排序的算法思想我这里不再赘述,直接上代码.存在错误之处望指正,大家一起进步! --------------------------------------------------------- ...

  5. 八大排序Java代码(新)

    八大排序 冒泡排序(稳定) 选择排序(不稳) 插入排序(稳定) 希尔排序(不稳) 快速排序(不稳) 归并排序(稳定) 基数排序(稳定) 堆排序(不稳) 冒泡排序(稳定) public class Bu ...

  6. java圆形排列_位图排序java版

    1.<编程珠玑>第一章第一题就相当的精彩,做个笔记.题目如下: 输入:   一个包含n个正整数的文件,每个正整数小于n,n等于10的7次方(一千万).并且文件内的正整数没有重复和关联数据. ...

  7. 八大排序算法(java实现) 冒泡排序 快速排序 堆排序 归并排序 等

    八大排序算法 一.直接插入 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 二.希尔排序 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 三.简单选择 - 1. ...

  8. java 快排_八大排序-快速排序(搞定面试之手写快排)

    概要 快速排序由C. A. R. Hoare在1960年提出,是八大排序算法中最常用的经典排序算法之一.其广泛应用的主要原因是高效,核心算法思想是分而治之.快速排序经常会被作为面试题进行考察,通常的考 ...

  9. Twitter的分布式雪花算法 SnowFlake 每秒自增生成26个万个可排序的ID (Java版)

    分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有些时候我们希望能使用一种简单一 ...

最新文章

  1. linux命令历史详解
  2. c#中在工作线程创建窗体并操作
  3. Quarkus on OpenJ9 JVM和资源消耗
  4. QtJava笔记-Qt与Java进行SSL双向认证(Qt服务端,Java客户端)
  5. C语言物业费管理系统设计,基于SSM框架的物业缴费管理系统设计与实现源码
  6. JDK命令一、javah命令(C Header and Stub File Generator)
  7. 51单片机之实时秒表
  8. 一文读懂HBase的存储模式--BigTable
  9. 阿里云用域名、ip访问不了网站
  10. Windows 10怎样安装.msi文件?三分钟解决问题
  11. C++后台开发推荐的书
  12. 【蓝桥杯集训·每日一题】AcWing 3777. 砖块
  13. ExifTool常用使用方法
  14. 开源项目之Android繁体中文输入法
  15. opencv光线补偿_光线补偿算法的实现
  16. 使用switch语句根据消费金额计算折扣
  17. Python 题之“大小写字母互换”
  18. mysql中sql插入时间_mysql中使用sql语句插入日期时间类型的写法
  19. SQL IN(规定多个值) 和 BETWEEN(选取介于两个值之间的数据范围) 操作符
  20. 2022年注册会计师(CPA)考试模拟题及答案

热门文章

  1. Cisco(思科)远程登录路由器
  2. 摩西十诫——自我约束
  3. python实现回合制对战小游戏
  4. 百度李彦宏登上《时代周刊》整个互联网都在比心
  5. 10 种最流行的 Web 挖掘工具 | 程序员硬核评测
  6. 有关SEO效果评估的七大指标你知道吗?
  7. MTK 双摄算法集成
  8. 浅谈MySQL数据库备份的几种方法
  9. 图片标注工具LabelImg安装及使用
  10. 一道题目入门VMpwn