《算法》逆序数组,选择排序和插入排序谁更快

来源:互联网 发布:mac 终端翻墙 编辑:程序博客网 时间:2024/06/03 07:47

2.1.6  在所有的主键都相同时,选择排序和插入排序谁更快?

插入排序更快

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[N];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[N];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[N];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。


阅读全文
0 0
原创粉丝点击