文章目录

  • 一, 直接插入排序
  • 二,希尔排序
  • 三、选择排序
  • 四,堆排序
  • 五,冒泡排序
  • 六,快速排序
    • 如何优化快排呢?
    • 三数取中法优化快排
  • 七,归并排序


怎么判断是不是稳定的排序呢?
如果当前这个序列,在排序的过程中,没有发生跳跃式的交换,那么我们就认为这个排序是稳定的排序。

一, 直接插入排序

特点:效率低,容易实现。
原理:将数组分为两部分,将后部分元素逐一插入前部分有序元素的适当位置
时间复杂度:最好 当数据有序时O(n) 最坏 O(n^2)
空间复杂度 O(1)
稳定的排序

public static void insertSort(int[] array){for(int i=1;i<array.length;i++){int tmp=array[i];//后部分第一个数int j=i-1;for(;j>=0;j--){if(array[j]>tmp){array[j+1]=array[j];}else {break;}}array[j+1]=tmp;}}

二,希尔排序

原理:希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。
先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。
时间复杂度:最好O(n) 最坏O(n^2)
空间复杂度 O(1)
不稳定的排序

保证gap是素数,最后一个是1就可以了


public static void shell(int[] array ,int gap) {for(int i=gap;i<array.length;i++){int tmp=array[i];int j=i-gap;for(;j>=0;j=j-gap){if(array[j]>tmp){array[j+gap]=array[j];}else{break;}}array[j+gap]=tmp;}}public static void shellSort(int[] array){int[] drr={5,3,1};//增量数组for(int i=0;i<drr.length;i++){shell(array,drr[i]);}}

三、选择排序

时间复杂度:O(n^2)
空间复杂度 O(1)
不稳定的排序

特点:效率低,容易实现。
原理:就是每次遍历一趟,找出最小的数,放到最前端,直到全部待排序的数据元素排完。 (这里说的是最前,是指无序的队列中的最前)

public static void selectSort(int[] array) {for (int i = 0; i < array.length-1; i++) {for (int j = i+1; j < array.length; j++) {if(array[j] < array[i]) {int tmp = array[j];array[j] = array[i];array[i] = tmp;}}}}

四,堆排序

原理:是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
时间复杂度:O(logn)
空间复杂度 O(1)
不稳定的排序

public class Priority {//从小到大排序public static void heapSort(int[] array){crateBigHeap(array);int end=array.length-1;while(end>0){int tmp=array[0];array[0]=array[end];array[end]=tmp;adjustDown(array,0,end);end--;}}public static void adjustDown(int[] array,int parent, int len) {int child = 2 * parent + 1;//child<len 说明有左孩子while (child < len) {// child + 1 < len 判断是 当前是否 有右孩子if (child + 1 < len && array[child] < array[child + 1]) {child++;//}// child 下标 一定是 左右孩子的最大值下标if (array[child] > array[parent]) {int tmp = array[child];array[child] = array[parent];array[parent] = tmp;parent = child;child = 2 * parent + 1;} else {//因为是从最后一棵树开始调整的  只要我们 找到了这个// this.elem[child] <= this.elem[parent]   后续就不需要循环了//后面的都已经是大根堆了break;}}}public static void crateBigHeap(int[] array) {for (int i = (array.length - 1 - 1) / 2; i >= 0; i--) {adjustDown(array,i, array.length);}}

五,冒泡排序

最常见的排序实现起来很简单,不过实际应用很少,复杂度O(n²)。
原理:如果假设长度为n的数组array,按照从小到大排序,首先从数组的第一个元素开始到数组最后一个元素为止,对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,则交换这两个元素在数组中的位置,此时数组最右端的元素即为该数组中所有元素的最大值。接着对该数组剩下的n-1个元素进行冒泡排序,直到整个数组有序排列。算法的时间复杂度为O(n^2)。

比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

时间复杂度:O(n^2)
空间复杂度 O(1)
稳定的排序

 public static void BubbleSort(int []array){for(int i=1;i<array.length;i++) {   for(int j=0;j<array.length-1;j++) {if(array[j]>array[j+1]) {int temp=array[j];array[j]=array[j+1];array[j+1]=temp;}}for(int i=0;i<array.length;i++) {System.out.print(array[i]+" ");}System.out.println();}}

六,快速排序

特点:高效,时间复杂度最好为O(nlogn)最坏O(n^2)。
空间复杂度:O(logn)
不稳定的排序
原理:1. 从待排序区间选择一个数,作为基准值(pivot)
2. 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可以包含相等的)放到基准值的右边;
3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间的长度 == 0,代表没有数据。

分治思想什么时候效率最高?每次把待排序序列均匀的划分为若干份

//快速排序public static int pivot(int[] array,int start,int end) {int tmp = array[start];while (start < end) {while (start<end&&array[end]>tmp) {end--;}//把数据赋值给startarray[start]=array[end];while (start<end&&array[start]<tmp) {start++;}//把start下标的值给endarray[end]=array[start];}array[start] = tmp;return start;}public static void quick(int [] array,int low,int high){if(low<high){int piv= pivot(array,low,high);quick(array,low,piv-1);quick(array,piv+1,high);}}public static void main(String[] args) {int[] array={12,32,1,3,4,5,45,6,88,77};System.out.println(Arrays.toString(array));quick(array,0,array.length-1);System.out.println(Arrays.toString(array));}
}

如何优化快排呢?

随机选取基准法
做法:随机找到后边的一个下标,然后和Low下标的数据进行交换,然后以low下标交换的值作为基准

三数取中法优化快排

//快速排序public static int pivot(int[] array,int start,int end) {int tmp = array[start];while (start < end) {while (start<end&&array[end]>tmp) {end--;}//把数据赋值给startarray[start]=array[end];while (start<end&&array[start]<tmp) {start++;}//把start下标的值给endarray[end]=array[start];}array[start] = tmp;return start;}public static void swap(int[] array,int k,int i){int tmp=array[k];array[k]=array[i];array[i]=tmp;}//快速排序的优化public static void medianOfThree(int [] array,int low,int high){int mid=(low+high)/2;//array[mid]<=array[low]<=array[high]if(array[low]<array[mid]){//array[mid] <= array[low]swap(array,mid,low);}if(array[low]>array[high]){//array[low] <= array[high]swap(array,high,low);}if(array[mid]<array[high]){//array[mid] <= array[high]swap(array,mid,high);}}public static void quick(int [] array,int low,int high){if(low<high){medianOfThree(array,low,high);int piv= pivot(array,low,high);quick(array,low,piv-1);quick(array,piv+1,high);}}public static void main(String[] args) {int[] array={12,32,1,3,4,5,45,6,88,77};System.out.println(Arrays.toString(array));quick(array,0,array.length-1);System.out.println(Arrays.toString(array));}
}

七,归并排序

原理:采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。

//合并
public static void merge(int[] array,int start,int mid,int end) {int s1 = start;int s2 = mid+1;int[] tmp = new int[end-start+1];int k = 0;//tmp数组的下标while (s1 <= mid && s2 <= end) {if(array[s1] <= array[s2]) {tmp[k++] = array[s1++];}else{tmp[k++] = array[s2++];}}//有可能第一个段还有数据 有可能第2个段也有数据while (s1 <= mid) {tmp[k++] = array[s1++];}while (s2 <= end){tmp[k++] = array[s2++];}for (int i = 0; i < tmp.length; i++) {array[i+start] = tmp[i];}}
//分解public static void mergeSortInternal(int[] array,int low,int high) {if(low >= high) return;int mid = (low+high)/2;mergeSortInternal(array,low,mid);mergeSortInternal(array,mid+1,high);//合并的操作merge(array,low,mid,high);}
public static void mergeSort(int[] array){mergeSortinternal(array,0,array.length-1);}public static void main(String[] args) {int[] array={12,32,1,3,4,5,45,6,88,77};System.out.println(Arrays.toString(array));mergeSort(array);System.out.println(Arrays.toString(array));
}

常见七种排序算法对比(超全!!!)相关推荐

  1. java 算法 排序算法_Java七种排序算法以及实现

    Java常见七种排序算法以及实现 最近学习一些排序算法,怕自己以后忘记就打算整理起来供自己复习 萌新一枚学习Java没多久,以下仅供参考.如有错误希望大佬指正,欢迎大家在评论区交流探讨. 1.冒泡排序 ...

  2. 七种排序算法(C++)

    排序算法 引言 冒泡排序 简单选择排序 直接插入排序 希尔排序 堆排序 归并排序 快速排序 引言 排序中主要包含数据元素的比较和交换,本文以C++实现以下七种排序算法,以从小到大排序为例. 如有错误, ...

  3. 数据结构(三) 用java实现七种排序算法。

    很多时候,听别人在讨论快速排序,选择排序,冒泡排序等,都觉得很牛逼,心想,卧槽,排序也分那么多种,就觉得别人很牛逼呀,其实不然,当我们自己去了解学习后发现,并没有想象中那么难,今天就一起总结一下各种排 ...

  4. 【数据结构】用java实现不同的七种排序算法和性能比较

    文章目录 1.直接插入排序 2.希尔排序 3.冒泡排序 4.快速排序 5.选择排序 6.堆排序 7.归并排序 1.直接插入排序 public class DifferentSort {public s ...

  5. Python实现经典七种排序算法

    #2018-06-02 June Saturday the 22 week, the 153 day SZ #数组排序算法大全用Python3实现 #参考https://www.cnblogs.com ...

  6. 数据结构常用的七种排序算法总结

    前言 排序算法在数据结构里属于最为重要的一部分,例如我们熟悉的冒泡.选择.插入.归并等,这些当初在第一次学习的时候,并没有很好的掌握,现在因为在备战考研,刚刚进行完数据结构的一轮简单复习在开始整理一轮 ...

  7. 用JS实现的常见几种排序算法

    1.快速排序法 /*快速排序法*/ function quickSort(a) { if (a.length <= 1) { return a; } var midLength = Math.f ...

  8. 面试常见几种排序算法 Java代码总结

    以下所有swap方法里面的代码都与如下代码等价: int tenp = arr[i]; arr[i] = arr[j]; arr[j] = temp; mid = (left + right) / 2 ...

  9. Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

    本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...

最新文章

  1. sql镶嵌查询_sql数据库的嵌套查询
  2. pymongo多结果进行多列排序的代码
  3. iOS UITableView的方法解析
  4. java long 对应mybati类型_修改 mybatis-generator 中数据库类型和 Java 类型的映射关系...
  5. QT如何设置应用程序的图标
  6. 【转】从零开始学图形学:10分钟看懂贝塞尔曲线
  7. SQL Servr 2008空间数据应用系列一:空间信息基础
  8. JVM虚拟机-Class文件之属性表集合
  9. 它在计算机房的旁边英文,计算机房设备搬迁协议 (中英文)
  10. 如何学好Python自动化,每个进阶的测试人都应该看看
  11. git 生成多个patch_git生成Patch和打Patch
  12. 编程语言(C语言,JAVA),程序设计,APP开发,算法
  13. ❤️Docker教程小白实操入门 教程合集❤️
  14. filenet安装前置工作-总结安装一天的成果
  15. Nuvoton M031-时钟树
  16. 计算机考试上网题操作步骤,计算机等级考试一级复习 上网试题操作方法-
  17. Pinbox使用感受
  18. Linux 下 输入账号 密码 显示 last login:Mon Apr 1 05:49:00 on tty1 但是跳转不进去系统?
  19. 李开复写给中国大学生的第五封信
  20. android 记住多个账号,Android实现记住账号密码功能

热门文章

  1. mysql 查询缓存设置
  2. 我的天使很调皮(淡月儿)
  3. MFC中GetDlgItem()和GetWindowText()获取控件里面的数据并保存下来
  4. z3学习笔记(python 3)
  5. 机器学习--线性回归R语言
  6. tomcat是虚拟服务器吗,tomcat 虚拟主机是什么意思
  7. 解决VMWARE horizon 发布后字体没有的问题。
  8. ESXI6.7 windows虚拟机 取消Vmware Tools分辨率自适应/固定分辨率
  9. Super的基本用法
  10. 多地目击超级UFO:巨型球状发光体悬挂空中