阅读本文约需要7分钟

大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈)。上次老师跟大家分享了下用Navicat for Mysql导入.sql文件的相关知识,今天跟大家分享在 各种排序算法的分析及java实现(一)的知识。

参考来源:https://www.cnblogs.com/liuling/p/2013-7-24-01.html

新的一周又开始了,这周也要打起精神好好加油!今天我们开始了解排序。

排序大的分类可以分为两种:内排序和外排序。在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序。下面讲的排序都是属于内排序。

内排序有可以分为以下几类:

  (1)、插入排序:直接插入排序、二分法插入排序、希尔排序。

  (2)、选择排序:简单选择排序、堆排序。

  (3)、交换排序:冒泡排序、快速排序。

  (4)、归并排序

  (5)、基数排序

一、插入排序

•思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置,直到全部插入排序完为止。

•关键问题:在前面已经排好序的序列中找到合适的插入位置。

•方法:

–直接插入排序

–二分插入排序

–希尔排序

①直接插入排序(从后向前找到合适位置后插入)

1、基本思想

每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。

2、实例

  

 3、java实现

 package com.sort;    public class 直接插入排序 {      public static void main(String[] args) {          int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};          System.out.println("排序之前:");          for (int i = 0; i < a.length; i++) {              System.out.print(a[i]+" ");         }         //直接插入排序         for (int i = 1; i < a.length; i++) {             //待插入元素             int temp = a[i];             int j;             /*for (j = i-1; j>=0 && a[j]>temp; j--) {                 //将大于temp的往后移动一位                 a[j+1] = a[j];             }*/             for (j = i-1; j>=0; j--) {                 //将大于temp的往后移动一位                 if(a[j]>temp){                     a[j+1] = a[j];                 }else{                     break;                 }             }             a[j+1] = temp;         }         System.out.println();         System.out.println("排序之后:");         for (int i = 0; i < a.length; i++) {             System.out.print(a[i]+" ");         }     } }

4、分析

直接插入排序是稳定的排序。关于各种算法的稳定性分析可以参考

http://www.cnblogs.com/Braveliu/archive/2013/01/15/2861201.html

文件初态不同时,直接插入排序所耗费的时间有很大差异。若文件初态为正序,则每个待插入的记录只需要比较一次就能够找到合适的位置插入,故算法的时间复杂度为O(n),这时最好的情况。若初态为反序,则第i个待插入记录需要比较i+1次才能找到合适位置插入,故时间复杂度为O(n2),这时最坏的情况。直接插入排序的平均时间复杂度为O(n2)。

②二分法插入排序(按二分法找到合适位置插入)

  1、基本思想

二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。

  2、实例

  3、java实现

 package com.sort;  public class 二分插入排序 {      public static void main(String[] args) {          int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};          System.out.println("排序之前:");          for (int i = 0; i < a.length; i++) {              System.out.print(a[i]+" ");          }        //二分插入排序         sort(a);         System.out.println();         System.out.println("排序之后:");         for (int i = 0; i < a.length; i++) {             System.out.print(a[i]+" ");         }     }     private static void sort(int[] a) {         for (int i = 0; i < a.length; i++) {             int temp = a[i];             int left = 0;             int right = i-1;             int mid = 0;             while(left<=right){                 mid = (left+right)/2;                 if(temp                     right = mid-1;                 }else{                     left = mid+1;                 }             }             for (int j = i-1; j >= left; j--) {                 a[j+1] = a[j];             }             if(left != i){                 a[left] = temp;             }         }     } }

  4、分析

 当然,二分法插入排序也是稳定的。二分插入排序的比较次数与待排序记录的初始状态无关,仅依赖于记录的个数。当n较大时,比直接插入排序的最大比较次数少得多。但大于直接插入排序的最小比较次数。算法的移动次数与直接插入排序算法的相同,最坏的情况为n2/2,最好的情况为n,平均移动次数为O(n2)。

③希尔排序

 1、基本思想:

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序。

然后,取第二个增量d2

  2、实例

 3、java实现

 package com.sort;  //不稳定  public class 希尔排序 {      public static void main(String[] args) {          int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};          System.out.println("排序之前:");         for (int i = 0; i < a.length; i++) {             System.out.print(a[i]+" ");         }         //希尔排序         int d = a.length;         while(true){             d = d / 2;             for(int x=0;x                 for(int i=x+d;i                     int temp = a[i];                     int j;                     for(j=i-d;j>=0&&a[j]>temp;j=j-d){                         a[j+d] = a[j];                     }                     a[j+d] = temp;                 }             }             if(d == 1){                 break;             }         }         System.out.println();         System.out.println("排序之后:");         for (int i = 0; i < a.length; i++) {             System.out.print(a[i]+" ");         }     } }

  4、分析

我们知道一次插入排序是稳定的,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。希尔排序的时间性能优于直接插入排序,原因如下:

(1)当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。(2)当n值较小时,n和n2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(n2)差别不大。(3)在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。因此,希尔排序在效率上较直接插人排序有较大的改进。希尔排序的平均时间复杂度为O(nlogn)。

二、选择排序

•思想:每趟从待排序的记录序列中选择关键字最小的记录放置到已排序表的最前位置,直到全部排完。

•关键问题:在剩余的待排序记录序列中找到最小关键码记录。

•方法:

–直接选择排序

–堆排序

①简单的选择排序

  1、基本思想

在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

  2、实例

  3、java实现

  package com.sort;  //不稳定  public class 简单的选择排序 {      public static void main(String[] args) {         int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};          System.out.println("排序之前:");          for (int i = 0; i < a.length; i++) {             System.out.print(a[i]+" ");         }         //简单的选择排序         for (int i = 0; i < a.length; i++) {             int min = a[i];             int n=i; //最小数的索引             for(int j=i+1;j                 if(a[j]                     min = a[j];                     n = j;                 }             }             a[n] = a[i];             a[i] = min;         }         System.out.println();         System.out.println("排序之后:");         for (int i = 0; i < a.length; i++) {             System.out.print(a[i]+" ");         }     } }

 4、分析

  简单选择排序是不稳定的排序。

 时间复杂度:T(n)=O(n2)。

②堆排序

 1、基本思想:

堆排序是一种树形选择排序,是对直接选择排序的有效改进。

堆的定义下:具有n个元素的序列 (h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1) (i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。

由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二 叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。

思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个 堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。

依此类推,直到只有两个节点的堆,并对 它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。

  2、实例

初始序列:46,79,56,38,40,84建堆:

  交换,从堆中踢出最大数

依次类推:最后堆中剩余的最后两个结点交换,踢出一个,排序完成。

  3、java实现

  package com.sort;  //不稳定  import java.util.Arrays;  public class HeapSort {      public static void main(String[] args) {          int[] a={49,38,65,97,76,13,27,49,78,34,12,64};          int arrayLength=a.length;            //循环建堆           for(int i=0;i             //建堆               buildMaxHeap(a,arrayLength-1-i);               //交换堆顶和最后一个元素               swap(a,0,arrayLength-1-i);               System.out.println(Arrays.toString(a));           }       }     //对data数组从0到lastIndex建大顶堆     public static void buildMaxHeap(int[] data, int lastIndex){          //从lastIndex处节点(最后一个节点)的父节点开始          for(int i=(lastIndex-1)/2;i>=0;i--){             //k保存正在判断的节点             int k=i;             //如果当前k节点的子节点存在              while(k*2+1<=lastIndex){                 //k节点的左子节点的索引                  int biggerIndex=2*k+1;                 //如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在                 if(biggerIndex                     //若果右子节点的值较大                       if(data[biggerIndex]                         //biggerIndex总是记录较大子节点的索引                           biggerIndex++;                       }                   }                   //如果k节点的值小于其较大的子节点的值                   if(data[k]                     //交换他们                       swap(data,k,biggerIndex);                       //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值                       k=biggerIndex;                   }else{                       break;                   }               }         }     }     //交换     private static void swap(int[] data, int i, int j) {           int tmp=data[i];           data[i]=data[j];           data[j]=tmp;       }  }

  4、分析

堆排序也是一种不稳定的排序算法。

堆排序优于简单选择排序的原因:

直接选择排序中,为了从R[1..n]中选出关键字最小的记录,必须进行n-1次比较,然后在R[2..n]中选出关键字最小的记录,又需要做n-2次比较。

事实上,后面的n-2次比较中,有许多比较可能在前面的n-1次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这些比较操作。

堆排序可通过树形结构保存部分比较结果,可减少比较次数。

堆排序的最坏时间复杂度为O(nlogn)。堆序的平均性能较接近于最坏性能。由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

今天就分享这么多,关于各种排序算法的分析及java实现(一),你学会了多少?欢迎在留言区评论,对于有价值的留言,我们都会一一回复的。如果觉得文章对你有一丢丢帮助,请点右下角【在看】,让更多人看到该文章。如果有想了解的,也可以进行留言

java实现apriori算法_各种排序算法的分析及java实现(一)相关推荐

  1. java常见的排序算法_常见排序算法及Java实现

    先上个总图↓: ①.直接插入排序 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并 ...

  2. python常见的排序算法_常见排序算法之python实现

    1. 冒泡排序 时间复杂度为O(n^2), 稳定的排序算法 思路:一开始比较的区间是[0,n-1],依次比较相邻两数,哪个数大哪个数就放在后面,这样一次遍历数组后,最大的数会在数组的最后一个位置,然后 ...

  3. 快速排序算法_常用排序算法之快速排序

    点击上方蓝色 "铁匠学编程" 关注我,让我们一起学习! 前天给大家分享了归并排序,但是它不是原地排序算法,需要消耗额外的内存空间,今天给大家分享的是江湖无人不知无人不晓的" ...

  4. 解释什么是快速排序算法?_解释排序算法

    解释什么是快速排序算法? Sorting algorithms are a set of instructions that take an array or list as an input and ...

  5. 起泡排序算法_气泡排序算法

    起泡排序算法 When working with large databases, it is necessary to add the functionality to search for val ...

  6. c语言合并排序算法_合并排序算法

    c语言合并排序算法 Merge Sort follows the rule of Divide and Conquer to sort a given set of numbers/elements, ...

  7. 用java编写验证码程序_编写,验证和分析实时Java应用程序

    本文是" 用实时Java开发"系列的第三篇也是最后一部分,展示了如何设计,编写,验证和分析基本的实时应用程序. 我们将说明: 应用程序的时间和性能要求. 为什么传统的非实时Java ...

  8. 快速排序算法_常用排序算法专题—快速排序

    黑客技术点击右侧关注,了解黑客的世界! Linux编程点击右侧关注,免费入门到精通! 程序员严选甄选正品好物,程序员生活指南! 作者丨就是彬彬呀https://www.jianshu.com/p/17 ...

  9. java开启一个线程_【jdk源码分析】java多线程开启的三种方式

    1.继承Thread类,新建一个当前类对象,并且运行其start()方法 1 packagecom.xiaostudy.thread;2 3 /** 4 * @desc 第一种开启线程的方式5 *@a ...

最新文章

  1. 【EventBus】EventBus 源码解析 ( 注册订阅者总结 | 从封装的数据结构角度分析 EventBus )
  2. c++ vector方法
  3. 10 过滤器和监听器
  4. 如何在一家大公司里受到重用
  5. 时间操作(Java版)—将毫秒转换为年月日时分秒
  6. poj1466二分图
  7. 正则表达式去除html标签
  8. VMD变分模态分解代码,C++代码下载
  9. vmware VCPU的一点理解记录
  10. Linux基础(三)
  11. Faster:一个高效就地更新的并发键值存储
  12. android 手表解决方案,智能手表解决方案
  13. 中国(成都)区块链博物馆为区块链正名
  14. YS-FS150型电缆防水接头的操作步骤
  15. xp进入win7计算机要密码怎么设置密码,XP系统设置直接跳过密码的多种方法
  16. 支付宝赚赏金的多种玩法(引流+变现日入200+)
  17. C++不知算法系列之高精度数值处理算法
  18. 码农在使用人脸识别开发套件中的硬件主板如何调用底层接口步骤
  19. 交叉编译ffmpeg+移植Hi3536板子
  20. 将DataFrame中的时间转换为时间戳

热门文章

  1. Elasticsearch生态技术峰会 | Elasticsearch在企查查的应用实践
  2. 码住!Flink Contributor 速成指南
  3. 十年沉淀,阿里云发布全球领先的对象存储OSS可用性SLA
  4. 基于阿里云MaxCompute实现游戏数据运营
  5. 用aliplayer如何实现视频的连续播放?
  6. ​如何成为一个更好的 React 开发者?
  7. 财报上新不久的Mobvista,还内藏何种“惊艳”?
  8. 生产环境使用HBase,你必须知道的最佳实践
  9. 京东技术全景图首次展示 四大重磅智能技术驱动产业未来
  10. 数据中台送到家 企业数字化转型“输血”变“造血”