说明

对排序实现的总结,以下都是基于升序排序[1,2,3…]:

插入排序:
两层循环嵌套,第一层从第二位开始,index逐步递增;
第二层,innerIndex从index-1逐步递减,,在index之前都为有序,如果data[innerIndex] > data[index],则innerIndex++腾出位置(这是插入排序的特点),一直到条件失败,退出内存循环,交换innerIndex 跟index。平均时间复杂度为O(n^2)


归并排序: 递归实现,先逐层一分为二,一直到只有一个数字,然后把拆解出来的数字逐层合并回来。复杂度分解为二叉树,合并为倒二叉树,时间复杂度为O(nlogn)


快速排序:快速排序的特点是取一个值为参考值pivot,小于pivot的在左边,大于pivot的在右边,这样左边的数据就不需要跟右边的数据比较,效率明显提高。但是,极端情况下,取得pivot一边都是只有一个值,就退化为另一边都是满数据,退化为冒泡排序了。为了逆序导致的复杂度退化为O(n^2), 这里用三者取中值法,来实现快速排序。平均时间复杂度为O(nlogn).


堆排序:堆实际为完全二叉树,也就是用数组为容器。
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
先建大顶堆,然后把顶端的值跟最后的值交换,堆大小减一,再次构建大顶堆。重复以上步骤,一直到堆减少为空,数组就是一个递增序列。
分析复杂度:建堆的时候,从节点开始遍历,length/2 - 1为index最大的节点,因为叶子节点2*(length/2 - 1) + 1 = length -1 , 反证法如果length/2为index最大的节点,那么叶子节点2*(length/2) + 1 = length +1, 超过容量。建堆每个节点排序时间复杂度为O(logn), 所以建堆复杂度为n/2 * logn; 每次去掉最大值再次建堆,时间复杂度小于 n* logn。 两个过程的和小于3n/2 *logn, 时间复杂度为O(nlogn).


代码 – 插入排序

import java.util.Arrays;public class InsertionSort {public void insertSort(int[] data) {for (int i = 1; i < data.length; i++) {int currentNumber = data[i];int j = i - 1;while (j >= 0 && data[j] > currentNumber) {data[j + 1] = data[j];j--;}data[j+1] = currentNumber;}}public static void main(String[] args) {int[] data = new int[]{4, 6, 5, 3, 7, 1, 2};System.out.println(Arrays.toString(data));InsertionSort obj = new InsertionSort();obj.insertSort(data);System.out.println(Arrays.toString(data));}
}

代码 – 归并排序

import java.util.Arrays;public class MergeSort {public void mergeSort(int[] data) {int[] temp = new int[data.length];subMergeSort(data, 0, data.length - 1, temp);}public void subMergeSort(int[] data, int left, int right, int[] temp) {if (left < right) {int mid = left + (right - left) / 2;subMergeSort(data, left, mid, temp);subMergeSort(data, mid + 1, right, temp);merge(data, left, mid, right, temp);}}public void merge(int[] data, int left, int mid, int right, int[] temp) {int i = left;int k = mid + 1;int t = 0;while (i <= mid && k <= right) {if (data[i] < data[k]) {temp[t++] = data[i++];} else {temp[t++] = data[k++];}}while (i <= mid) {temp[t++] = data[i++];}while (k <= right) {temp[t++] = data[k++];}t = 0;while (left <= right) {data[left++] = temp[t++];}}public static void main(String[] args) {int[] data = new int[]{4, 6, 5, 3, 7, 1, 2};System.out.println(Arrays.toString(data));MergeSort obj = new MergeSort();obj.mergeSort(data);System.out.println(Arrays.toString(data));}}

代码 – 快速排序

import java.util.Arrays;public class QuickSort {public static void quickSort(int[] data) {// divide to left, right indexsubQuickSort(data, 0, data.length - 1);}public static void subQuickSort(int[] data, int leftIndex, int rightIndex) {if (leftIndex >= rightIndex) {return;}// pivot data: mid of the three number, and swap to right -1buildPivotCloseToRight(data, leftIndex, rightIndex);int i = leftIndex;int k = rightIndex - 1;int pivot = data[k];// two point from two side, ++left, --rightwhile (true) {// while ++left > pivotwhile ((i+1) < rightIndex && data[++i] < pivot) {}// while --right < pivotwhile ((k - 1) > leftIndex && data[--k] > pivot) {}// left < right, then swapif (i < k) {swap(data, i, k);} else {break;}}// if left < pivotIndex ,swapif (i < rightIndex - 1) {swap(data, i, rightIndex - 1);}// divide two sub quick sortsubQuickSort(data, leftIndex, i);subQuickSort(data, i + 1, rightIndex);}public static void buildPivotCloseToRight(int[] data, int leftIndex, int rightIndex) {int midIndex = leftIndex + (rightIndex - leftIndex) / 2;// swap small in left, between left, midif (data[leftIndex] > data[midIndex]) {swap(data, leftIndex, midIndex);}// swap small in left, between left, rightif (data[leftIndex] > data[rightIndex]) {swap(data, leftIndex, rightIndex);}// swap big in right, between mid, rightif (data[midIndex] > data[rightIndex]) {swap(data, midIndex, rightIndex);}// swap pivot int right -1swap(data, midIndex, rightIndex - 1);}public static void swap(int[] data, int i, int k) {int temp = data[i];data[i] = data[k];data[k] = temp;}public static void main(String[] args) {int[] data = new int[]{4, 6, 5, 3, 7, 1, 2};System.out.println(Arrays.toString(data));quickSort(data);System.out.println(Arrays.toString(data));}
}

代码 – 堆排序

import java.util.Arrays;public class HeapSort {public static void heapSort(int[] data) {// build top big heapfor (int i = data.length/2 -1; i >= 0; i--) {// build heapbuildHeap(data, i, data.length);}// change seat between the first and the last, length--for (int k = data.length - 1; k >=0; k--) {// change seat between first and last oneswap(data, 0, k);// build heapbuildHeap(data, 0, k);}}public static void buildHeap(int[] data, int nodeIndex, int length) {int temp = data[nodeIndex];for (int k = nodeIndex * 2 + 1; k < length; k = k * 2 + 1) {if (k + 1 < length && data[k] < data[k + 1]) {k = k + 1;}if (data[k] > temp) {data[nodeIndex] = data[k];nodeIndex = k;} else {break;}}data[nodeIndex] = temp;}public static void swap(int[] data, int i, int j) {int temp = data[i];data[i] = data[j];data[j] = temp;}public static void main(String[] args) {int[] data = new int[]{4, 6, 5, 3, 7, 1, 2};System.out.println(Arrays.toString(data));heapSort(data);System.out.println(Arrays.toString(data));}
}

运行结果

[4, 6, 5, 3, 7, 1, 2]
[1, 2, 3, 4, 5, 6, 7]

总结

排序实现一遍,bug free不容易,不信,请您试试?

代码下载:
https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/popular/Sorting/InsertionSort.java
https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/popular/Sorting/MergeSort.java
https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/popular/Sorting/QuickSort.java
https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/popular/Sorting/HeapSort.java

参考:
https://www.cnblogs.com/chengxiao/p/6103002.html
https://www.cnblogs.com/chengxiao/p/6194356.html
https://www.cnblogs.com/chengxiao/p/6262208.html
https://www.cnblogs.com/chengxiao/p/6129630.html
https://zh.wikipedia.org/wiki/排序算法

算法:插入排序、归并排序、快速排序、堆排序相关推荐

  1. 堆排序时间复杂度_leetcode刷题(二):排序算法(归并排序,堆排序,桶排序)...

    今天,我们要来讲讲排序问题,这次讲的排序算法主要是归并排序,堆排序和桶排序. 归并排序 归并一词在中文的含义就是"合并,并入"的意思,在数据结构里面就是将两个或者两个以上的有序数组 ...

  2. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  3. 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序

    这篇文章主要介绍了Java如何实现八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序,需要的朋友可以参考下 本文实现了八个常用的排序算法:插入排序 ...

  4. Algorithm:C++语言实现之内排序、外排序相关算法(插入排序 、锦标赛排序、归并排序)

    Algorithm:C++语言实现之内排序.外排序相关算法(插入排序 .锦标赛排序.归并排序) 目录 一.内排序 1.插入排序 2.锦标赛排序 3.归并排序 二.外排序 1.过程 一.内排序 1.插入 ...

  5. 排序算法:归并排序、快速排序

    相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 一.归并排序: 1.工作原理: 归 ...

  6. 重点算法排序之快速排序、归并排序(上篇)

    文章目录 一.排序的概念及常见的排序算法 二.快速排序的思想及代码详解 2.1 快速排序的思想 2.2 挖坑法 2.2.1 挖坑法实现思想 2.2.2 挖坑法举例 2.2.3 挖坑法代码实现 2.3 ...

  7. 排序算法中——归并排序和快速排序

    冒泡排序.插入排序.选择排序这三种算法的时间复杂度都为 $O(n^2)$,只适合小规模的数据.今天,我们来认识两种时间复杂度为 $O(nlogn)$ 的排序算法--归并排序(Merge Sort)和快 ...

  8. 排序算法之——归并排序和快速排序

    冒泡排序.插入排序.选择排序这三种算法的时间复杂度都为 O ( n 2 ) O(n^2) O(n2),只适合小规模的数据.今天,我们来认识两种时间复杂度为 O ( n l o g n ) O(nlog ...

  9. NOI提高级:排序算法之归并排序、快速排序

    图解排序算法(四)之归并排序 图解排序算法(四)之归并排序 - dreamcatcher-cx - 博客园 小学生图解排序算法:⑥归并排序 小学生图解排序算法:⑥归并排序_纯文笔记-CSDN博客_图解 ...

  10. php二分法 冒泡 快速排序,PHP 常见算法【冒泡排序, 快速排序, 插入排序, 取舍排序, 二分法查找, .】...

    PHP 常见算法[冒泡排序, 快速排序, 插入排序, 选择排序, 二分法查找, ..] // 冒泡排序 function bubblesort($arr) { for($i=0,$j=count($a ...

最新文章

  1. 福利 |《非结构化数据分析》书评:探索非结构化数据的魅力
  2. Tengine 反向代理状态检测
  3. mysql+如何开发存储引擎_干货!MySQL 的 InnoDB 存储引擎是怎么设计的?
  4. python迭代器生成器使用技巧(2):切片、遍历、索引值、多序列、多容器对象
  5. 如何让nodejs在linux后台运行
  6. GDB 调试命令讲解 2-转
  7. centos最新版solr5.3.1安装和数据整理以及遇到的问题解答
  8. python基础教程 pdf github_GitHub - looly/python-basic: 老齐(qiwsir)的Python基础教程Gitbook版...
  9. 大工20秋《计算机原理》在线作业2答案,奥鹏大工15秋《计算机组成原理》在线作业2满分答案...
  10. 大工微电子器件可靠性基础作业四威布尔分布小题求参数m和t0
  11. JAVA阿里云短信接口调用-傻瓜式教程
  12. r语言如何计算t分布临界值_「SPSS数据分析」SPSS差异分析(3)独立样本T检验操作步骤及解读...
  13. url 后面参数说明
  14. caffe 搭建参数服务器(1)—— 用MPI实现多节点同时训练一个模型
  15. 如何选购台式电脑和笔记本?购买时应注意什么
  16. 基于javaweb+jsp的个人日记管理系统(JavaWeb JSP MySQL Servlet SSM SpringBoot Layui Ajax)
  17. 如何用java判断手机号运营商?
  18. GItHub频繁验证邮箱?Please verify your email address????
  19. <数据结构>创建一个有理数类
  20. i=i+1 与 i+=1 区别

热门文章

  1. web.config中文解释
  2. ARTS打卡计划第一周-Tips-ControllerAdvice的使用
  3. 20.10 for循环 20.11/20.12 while循环 20.13 break跳出循环 20.14 continue结束本次循环 20.15 exit退出整个脚本...
  4. Java定时任务的三种实现方法
  5. Android -- Looper.prepare()和Looper.loop() —深入版
  6. 内部人示范(野生项目笔记02)
  7. 迷茫中,请指教,谢谢!
  8. C语言判断四个嫌疑犯问题,C语言谁是窃贼问题代码及解析
  9. c++如何生成指定范围的随机数
  10. 计蒜客-----单独的数字(map)