《算法》逆序数组,选择排序和插入排序谁更快
2017-09-13 11:25
357 查看
2.1.6 在所有的主键都相同时,选择排序和插入排序谁更快?
插入排序更快
2.1.7 对于逆序数组,选择排序和插入排序谁更快?
选择排序更快
为什么?看完代码后,再解释
一、插入排序的代码
二、选择排序的代码
三、算法时间比较的代码
四、运行算法时间比较的代码SortCompare.java进行比较
控制台输入: Insertion Selection 1000 100
输出结果(每个人电脑,每次结果都不同,不要慌):
Insertion Selection 1000 100
for 1000 random Doules
Insertion is 1.3 times faster than Selection
for 1000 equal Doules
Insertion is 213.0 times faster than Selection
for 1000 inverse Doules
Insertion is 0.9 times faster than Selection
五、解释
1、为什么所有的主键都相同时,插入排序更快?
数组元素都相同时
插入排序,比较次数N-1,交换次数0
选择排序,比较次数N(N-1)/2,交换次数0
2、为什么对于逆序数组,选择排序更快?
数组逆序时
插入排序,由于逆序对有N(N-1)/2对,所以交换次数是N(N-1)/2。比较次数大于等于交换次数,小于等于
交换次数+N-1。
选择排序,不管输入是怎样的,比较次数都是N(N-1)/2。此时交换次数为N-1。
插入排序更快
2.1.7 对于逆序数组,选择排序和插入排序谁更快?
选择排序更快
为什么?看完代码后,再解释
一、插入排序的代码
package test; import edu.princeton.cs.algs4.In; import edu.princeton.cs.algs4.StdOut; public class Insertion { public static void sort(Comparable[] a){ for(int i=1; i<a.length; i++){ for(int j=i; j>0 && less(a[j], a[j-1]); j--){ exch(a, j, j-1); } } } private static boolean less(Comparable v, Comparable w){ return v.compareTo(w) < 0; } private static void exch(Comparable[] a, int i, int j){ Comparable t = a[i]; a[i] = a[j]; a[j] = t; } private static void show(Comparable[] a){ for(int i=0; i<a.length; i++){ StdOut.print(a[i] + " "); } StdOut.println(); } public static boolean isSorted(Comparable[] a){ for(int i=1; i<a.length; i++){ if(less(a[i], a[i-1])) return false; } return true; } public static void main(String[] args){ String[] a = In.readStrings(); sort(a); assert isSorted(a); show(a); } }
二、选择排序的代码
package test; import edu.princeton.cs.algs4.In; import edu.princeton.cs.algs4.StdOut; public class Selection { public static void sort(Comparable[] a){ int N = a.length; for(int i=0; i<N; i++){ int min = i; for(int j=i+1; j<N; j++){ if(less(a[j], a[min])) min = j; } exch(a, i, min); } } private static boolean less(Comparable v, Comparable w){ return v.compareTo(w) < 0; } private static void exch(Comparable[] a, int i, int j){ Comparable t = a[i]; a[i] = a[j]; a[j] = t; } private static void show(Comparable[] a){ for(int i=0; i<a.length; i++){ StdOut.print(a[i] + " "); } StdOut.println(); } public static boolean isSorted(Comparable[] a){ for(int i=1; i<a.length; i++){ if(less(a[i], a[i-1])) return false; } return true; } public static void main(String[] args){ String[] a = In.readStrings(); sort(a); assert isSorted(a); show(a); } }
三、算法时间比较的代码
package test; import edu.princeton.cs.algs4.StdIn; import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdRandom; import edu.princeton.cs.algs4.Stopwatch; public class SortCompare { public static double time(String alg, Double[] a){ Stopwatch timer = new Stopwatch(); if(alg.equals("Insertion")) Insertion.sort(a); if(alg.equals("Selection")) Selection.sort(a); /*if(alg.equals("Shell")) Shell.sort(a); if(alg.equals("Merge")) Merge.sort(a); if(alg.equals("Quick")) Quick.sort(a); if(alg.equals("Heap")) Heap.sort(a);*/ return timer.elapsedTime(); } public static double timeRandomInput(String alg, int N, int T){ //使用算法alg,将T个长度为N的随机数组排序,所花的时间 double total = 0.0; Double[] a = new Double ; for(int t = 0; t < T; t++){ //进行一次测试(生成一个数组并排序) for(int i=0; i<N; i++){ a[i] = StdRandom.uniform(); } total += time(alg,a); } return total; } public static double timeEqualInput(String alg, int N, int T){ //使用算法alg, 将T个长度为N的数值全部相等的数组排序,所花的时间 double total = 0.0; Double[] a = new Double ; for(int i=0; i<N; i++){ //由于数组元素都相等,即使排序后,也相等,所以只赋值一次 a[i] = 1.0; } for(int t=0; t <T; t++){ total += time(alg, a); } return total; } public static double timeInverseInput(String alg, int N, int T){ //使用算法alg,将T个长度为N的逆序数组排序,所花的时间 double total = 0.0; Double[] a = new Double ; for(int t=0; t<T; t++){ for(int i=0; i<N; i++){ a[i] = 1.0 * (N-i); } total += time(alg, a); } return total; } public static void main(String[] args) { String alg1 = StdIn.readString(); String alg2 = StdIn.readString(); int N = StdIn.readInt(); int T = StdIn.readInt(); // 数组元素随机的情况下,插入排序快于选择排序 double t1 = timeRandomInput(alg1, N, T); double t2 = timeRandomInput(alg2, N, T); StdOut.printf("for %d random Doules\n %s is", N, alg1); StdOut.printf(" %.1f times faster than %s\n", t2/t1, alg2); // 数组元素都相等的情况下,插入排序快于选择排序 double t3 = timeEqualInput(alg1, N, T); double t4 = timeEqualInput(alg2, N, T); StdOut.printf("for %d equal Doules\n %s is", N, alg1); StdOut.printf(" %.1f times faster than %s\n", t4/t3, alg2); //数组元素逆序的情况下,插入排序慢于选择排序 double t5 = timeInverseInput(alg1, N, T); double t6 = timeInverseInput(alg2, N, T); StdOut.printf("for %d inverse Doules\n %s is", N, alg1); StdOut.printf(" %.1f times faster than %s\n", t6/t5, alg2); } }
四、运行算法时间比较的代码SortCompare.java进行比较
控制台输入: Insertion Selection 1000 100
输出结果(每个人电脑,每次结果都不同,不要慌):
Insertion Selection 1000 100
for 1000 random Doules
Insertion is 1.3 times faster than Selection
for 1000 equal Doules
Insertion is 213.0 times faster than Selection
for 1000 inverse Doules
Insertion is 0.9 times faster than Selection
五、解释
1、为什么所有的主键都相同时,插入排序更快?
数组元素都相同时
插入排序,比较次数N-1,交换次数0
选择排序,比较次数N(N-1)/2,交换次数0
2、为什么对于逆序数组,选择排序更快?
数组逆序时
插入排序,由于逆序对有N(N-1)/2对,所以交换次数是N(N-1)/2。比较次数大于等于交换次数,小于等于
交换次数+N-1。
选择排序,不管输入是怎样的,比较次数都是N(N-1)/2。此时交换次数为N-1。
相关文章推荐
- 对于逆序数组,,选择排序 和 插入排序 那个更快?
- Java排序算法(冒泡排序、选择排序、插入排序、反数组排序、快速排序)例子
- iOS开发--图形化排序算法比较:快速排序、插入排序、选择排序、冒泡排序
- 针对数组的三中排序方式:冒泡排序,选择排序,插入排序
- c语言中冒泡排序、插入排序、选择排序算法比较
- 必须知道的八大种排序算法【java实现】(二) 选择排序,插入排序,希尔算法【详解】
- 算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- 冒泡排序、选择排序、插入排序 算法实现
- 算法导论之插入排序,选择排序,归并排序,冒泡排序,希尔排序,堆排序,快速排序的c语言实现
- 算法_基本排序算法之冒泡排序,选择排序,插入排序和希尔排序
- java基本算法总结(冒泡排序、选择排序、插入排序)
- 常用算法--基本排序算法(冒泡排序,选择排序,插入排序,快速排序,归并排序,桶排序)
- php 经典算法,冒泡算法,快速排序,选择排序,插入排序
- PHP四种基础算法详解(冒泡排序、选择排序、插入排序、快速排序)
- c语言中冒泡排序、插入排序、选择排序算法比较
- C语言 选择排序算法原理和实现 从数组中 找出最小的元素然后交换位置
- c语言中冒泡排序、插入排序、选择排序算法比较
- 冒泡排序、选择排序、插入排序 算法实现(C++)
- c语言中冒泡排序、插入排序、选择排序算法比较