Java再学习-算法之插入排序
2016-05-10 10:57
239 查看
继上篇讲了冒泡排序的原理和代码,今天来讲一讲关于插入算法的逻辑。
和冒泡排序不同,排序算法,是选择一个元素依次和位于前面的元素进行比较。比如我选择的是第i个元素,则要判断第i-1个元素的大小。
插入排序也分成两套循环,外套循环比如是指针,来选择从第几个元素开始比较,而内套循环则要开始比较选择元素和前面元素的大小,进行排序。
代码如下:
执行结果:
大家可以看到每次循环排序的结果,和冒泡排序的不同之处,前面几次循环,并没有改变元素的顺序,在最后几次循环后,才开始进行排序。
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的
排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,
算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
最后对比一下冒泡和插入,在最好的情况,冒泡排序需要O(n^2)次交换,而插入排序只要最多O(n)交换。冒泡排序的实现(类似下面)
通常会对已经排序好的数列拙劣地运行(O(n^2)),而插入排序在这个例子只需要O(n)个运算。因此很多现代的算法教科书避免使用冒泡排序,
而用插入排序替换之。冒泡排序如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,也可以把最好的复杂度降低到O(n)。
在这个情况,已经排序好的数列就无交换的需要。若在每次走访数列时,把走访顺序反过来,也可以稍微地改进效率。有时候称为鸡尾酒排序,
因为算法会从数列的一端到另一端之间穿梭往返。
和冒泡排序不同,排序算法,是选择一个元素依次和位于前面的元素进行比较。比如我选择的是第i个元素,则要判断第i-1个元素的大小。
插入排序也分成两套循环,外套循环比如是指针,来选择从第几个元素开始比较,而内套循环则要开始比较选择元素和前面元素的大小,进行排序。
代码如下:
package cn.tgb.sort; import java.util.Arrays; //插入排序 public class InsertSort { public static void main(String[] args) { // 生成随机数 int[] values = new int[] { (int) (Math.random() * 100), (int) (Math.random() * 100), (int) (Math.random() * 100), (int) (Math.random() * 100), (int) (Math.random() * 100), (int) (Math.random() * 100), (int) (Math.random() * 100) }; // 打印出随机数 System.out.println(Arrays.toString(values)); // 从数组第二个元素开始排序,因为第一个元素本身肯定是已经排好序的 for (int i = 0; i < values.length; i++) { // 获取每i次循环的第i个元素 int key = values[i]; // 获取第i-1的序号 int j = i - 1; //如果是一个元素 则不进入循环 //依次跟之前的元素进行比较,如果发现比前面的原素小,则交换位置,最终完成排序。 while (j >= 0 && values[j] > key) { values[j + 1] = values[j]; values[j] = key; j--; } // 打印出每次的排序结果 System.out.println("第" + (i + 1) + "次排序"); for (int k = 0; k < values.length; k++) { System.out.print(values[k] + " "); } System.out.println(" "); } // 打印数组 // 最后打印出排序后的随机数 System.out.println(Arrays.toString(values)); } }
执行结果:
大家可以看到每次循环排序的结果,和冒泡排序的不同之处,前面几次循环,并没有改变元素的顺序,在最后几次循环后,才开始进行排序。
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的
排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,
算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
最后对比一下冒泡和插入,在最好的情况,冒泡排序需要O(n^2)次交换,而插入排序只要最多O(n)交换。冒泡排序的实现(类似下面)
通常会对已经排序好的数列拙劣地运行(O(n^2)),而插入排序在这个例子只需要O(n)个运算。因此很多现代的算法教科书避免使用冒泡排序,
而用插入排序替换之。冒泡排序如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,也可以把最好的复杂度降低到O(n)。
在这个情况,已经排序好的数列就无交换的需要。若在每次走访数列时,把走访顺序反过来,也可以稍微地改进效率。有时候称为鸡尾酒排序,
因为算法会从数列的一端到另一端之间穿梭往返。
相关文章推荐
- java.lang.UnsupportedClassVersionError错误的原因及解决方案
- Java7中的ForkJoin并发框架初探(中)——JDK中实现简要分析
- java 集合框架二(list)
- 优化eclipse编辑器,设置文本缩进
- JAVA容器的布局选择
- struts2详细配置
- Java程序设计总复习题
- Java集合---ConcurrentHashMap原理分析
- spring配置文件beans.xml的文档声明部分。
- java enum 举例
- Java 异常
- PAT-JAVA-5-31 字符串循环左移 (20分)
- java 集合框架一
- java类加载时机与过程
- PAT-JAVA-5-30 字符串的冒泡排序 (20分)
- Java流程控制
- Java synchronized详解
- Java struts2捕获404错误的方法汇总
- 提示通知框Notification
- PAT-java-5-29 删除字符串中的子串 (20分)