算法实验报告2

算法分析与设计实验报告

 

实验二 几种排序算法的实验性能比较

  1. 实验目的

实现插入排序(Insertion Sort,IS),自顶向下归并排序(Top-down Mergesort,TDM),自底向上归并排序(Bottom-up Mergesort,BUM),随机快速排序(Random Quicksort,RQ),Dijkstra 3-路划分快速排序(Quicksort with Dijkstra 3-way Partition,QD3P)。在你的

计算机上针对不同输入规模数据进行实验,对比上述排序算法的时间及空间占用性能。要求对于每次输入运行 10 次,记录每次时间/空间占用,取平均值。

  1. 实验环境

Java8  Eclipse  algs4.jar

  1. 实验内容

实现插入排序(Insertion Sort,IS),自顶向下归并排序(Top-down Mergesort,TDM),自底向上归并排序(Bottom-up Mergesort,BUM),随机快速排序(Random Quicksort,RQ),Dijkstra 3-路划分快速排序(Quicksort with Dijkstra 3-way Partition,QD3P)。在你的

计算机上针对不同输入规模数据进行实验,对比上述排序算法的时间及空间占用性能。要求对于每次输入运行 10 次,记录每次时间/空间占用,取平均值。

  1. 实验程序设计

(1)插入排序实现

package second_homework;

 

public class Is {

private static void exch(Comparable a[],int x,int y)

{

Comparable temp = a[x];

a[x] = a[y];

a[y] = temp;

}

public static void sort(Comparable a[])

{

int N = a.length;

for(int i=0;i<N;i++)

{

for(int j=i;j>0&&less(a[j],a[j-1]);j--)

{

exch(a,j,j-1);

}

}

}

 

private static boolean less(Comparable comparable, Comparable comparable2) {

// TODO 自动生成的方法存根

if(comparable.compareTo(comparable2)<0)

{

return true;

}

return false;

}

}

 

(2)自顶向下归并排序实现

package second_homework;

 

public class TDM {

private static Comparable[] aux;

private static void exch(Comparable a[],int x,int y)

{

Comparable temp = a[x];

a[x] = a[y];

a[y] = temp;

}

private static boolean less(Comparable comparable, Comparable comparable2) {

// TODO 自动生成的方法存根

if(comparable.compareTo(comparable2)<0)

{

return true;

}

return false;

}

public static void merge(Comparable a[],int lo,int mid,int hi)

{

int i=lo;

int j = mid+1;

for(int k=lo;k<=hi;k++)

aux[k] = a[k];

for(int k=lo;k<=hi;k++)

{

if(i>mid) a[k] = aux[j++];

else if(j>hi) a[k]=aux[i++];

else if(less(aux[i],aux[j]))

a[k] = aux[i++];

else 

a[k] = aux[j++];

}

}

public static void sort(Comparable a[])

{

int N = a.length;

aux= new Comparable[a.length];

sort(a,0,N-1);

 

}

private static void sort(Comparable a[],int lo,int hi)

{

if(hi<=lo) return;

int mid = lo + (hi - lo)/2;

sort(a,lo,mid);

sort(a,mid+1,hi);

merge(a,lo,mid,hi);

}

}

(3)自底向上的归并排序实现

package second_homework;

 

public class BUM {

private static Comparable[] aux;

private static boolean less(Comparable comparable, Comparable comparable2) {

// TODO 自动生成的方法存根

if(comparable.compareTo(comparable2)<0)

{

return true;

}

return false;

}

public static void merge(Comparable a[],int lo,int mid,int hi)

{

int i=lo;

int j = mid+1;

for(int k=lo;k<=hi;k++)

aux[k] = a[k];

for(int k=lo;k<=hi;k++)

{

if(i>mid) a[k] = aux[j++];

else if(j>hi) a[k]=aux[i++];

else if(less(aux[j],aux[i]))

a[k] = aux[j++];

else 

a[k] = aux[i++];

}

}

public static void sort(Comparable[] a)

{

int N = a.length;

aux = new Comparable[N];

for(int sz=1;sz<N;sz=sz+sz)

{

for(int lo = 0;lo<N-sz;lo+=sz+sz)

{

merge(a,lo,lo+sz-1,Math.min(N-1, lo+sz+sz-1));

}

}

}

}

 

(4)随机快速排序实现

package second_homework;

import edu.princeton.cs.algs4.StdRandom;

public class RQ {

private static boolean less(Comparable comparable, Comparable comparable2) {

// TODO 自动生成的方法存根

if(comparable.compareTo(comparable2)<0)

{

return true;

}

return false;

}

private static void exch(Comparable a[],int x,int y)

{

Comparable temp = a[x];

a[x] = a[y];

a[y] = temp;

}

public static void sort(Comparable[] a)

{

StdRandom.shuffle(a);

sort(a,0,a.length-1);

}

private static void sort(Comparable[] a,int lo,int hi)

{

if(hi<=lo) return;

int j = partion(a,lo,hi);

sort(a,lo,j-1);

sort(a,j+1,hi);

}

private static int partion(Comparable[] a,int lo, int hi)

{

int i=lo,j=hi+1;

Comparable v = a[lo];

while(true)

{

while(less(a[++i],v))

{

if(i == hi)

break;

}

while(less(v,a[--j]))

{

if(j==lo)

break;

}

if(i>=j)

break;

exch(a,i,j);

}

exch(a,lo,j);

return j;

}

}

 

(5)三向切分快速排序实现

package second_homework;

 

import edu.princeton.cs.algs4.StdRandom;

 

public class QD3P {

private static boolean less(Comparable comparable, Comparable comparable2) {

// TODO 自动生成的方法存根

if(comparable.compareTo(comparable2)<0)

{

return true;

}

return false;

}

private static void exch(Comparable a[],int x,int y)

{

Comparable temp = a[x];

a[x] = a[y];

a[y] = temp;

}

public static void sort(Comparable[] a)

{

StdRandom.shuffle(a);

sort(a,0,a.length-1);

}

private static void sort(Comparable[] a,int lo,int hi)

{

if(hi<=lo) return;

int lt=lo,i=lo+1,gt=hi;

Comparable v=a[lo];

while(i<=gt)

{

int cmp = a[i].compareTo(v);

if(cmp<0)

{

exch(a,lt++,i++);

}

else if(cmp>0)

{

exch(a,i,gt--);

}

else

i++;

}

sort(a,lo,lt-1);

sort(a,gt+1,hi);

}

}

 

(6)实验的主程序

package second_homework;

import edu.princeton.cs.algs4.StdRandom;

public class Sorting {

 

public static void show(Integer a[])

{

for(int i=0;i<a.length;i++)

{

System.out.print(a[i]);

System.out.print("  ");

if(i%10==0&&i!=0)

System.out.println();

}

System.out.println("\n-----------------------------");

}

public static void show(int a[])

{

for(int i=0;i<a.length;i++)

{

System.out.print(a[i]);

System.out.print("  ");

if(i%10==0&&i!=0)

System.out.println();

}

System.out.println("\n-----------------------------");

}

public static void main(String[] args) {

// TODO 自动生成的方法存根

System.out.println("针对100个数据进行实验");

System.out.println("原始数据如下");

int []TestData = new int[100];

Integer []TestData_1 = new Integer[100];

Integer []TestData_2 = new Integer[100];

Integer []TestData_3 = new Integer[100];

Integer []TestData_4 = new Integer[100];

Integer []TestData_5 = new Integer[100];

for(int i=0;i<100;i++)

{

TestData[i]=StdRandom.uniform(100);

TestData_1[i]=TestData_2[i]=TestData_3[i]=TestData_4[i]=TestData_5[i]=TestData[i];

}

Sorting.show(TestData);

Is.sort(TestData_1);

Sorting.show(TestData_1);

TDM.sort(TestData_2);

Sorting.show(TestData_2);

BUM.sort(TestData_3);

Sorting.show(TestData_3);

RQ.sort(TestData_4);

Sorting.show(TestData_4);

QD3P.sort(TestData_5);

Sorting.show(TestData_5);

System.out.println("这证明我的五个排序算法是正确的");

System.out.println("下面针对10000个数据进行实验,每次实验输入10次");

TestData = new int[10000];

TestData_1 = new Integer[10000];

long starttime = System.currentTimeMillis();

long endtime =  System.currentTimeMillis();

long realtime = (endtime - starttime)/10;

realtime = 0;

for(int j=0;j<10;j++)

{

for(int i=0;i<10000;i++)

{

TestData[i]=StdRandom.uniform(100);

TestData_1[i] = TestData[i];

}

starttime =  System.currentTimeMillis();

Is.sort(TestData_1);

endtime  =  System.currentTimeMillis();

realtime += (endtime - starttime);

System.out.println(endtime - starttime+"ms");

}

realtime /=10;

 

    System.out.println("插入排序实现,排序10000个数据,重复十次,时间为"+realtime+"毫秒");

    realtime = 0;

    for(int j=0;j<10;j++)

{

for(int i=0;i<10000;i++)

{

TestData[i]=StdRandom.uniform(100);

TestData_1[i] = TestData[i];

}

starttime =  System.currentTimeMillis();

TDM.sort(TestData_1);

endtime  =  System.currentTimeMillis();

realtime += (endtime - starttime);

System.out.println(endtime - starttime+"ms");

}

    

realtime /= 10;

    System.out.println("自顶向下的归并排序实现,排序10000个数据,重复十次,时间为"+realtime+"毫秒");

    realtime = 0;

    for(int j=0;j<10;j++)

{

for(int i=0;i<10000;i++)

{

TestData[i]=StdRandom.uniform(100);

TestData_1[i] = TestData[i];

}

starttime =  System.currentTimeMillis();

BUM.sort(TestData_1);

endtime  =  System.currentTimeMillis();

realtime += (endtime - starttime);

System.out.println(endtime - starttime+"ms");

}

    realtime /= 10;

    System.out.println("自顶向上的归并排序实现,排序10000个数据,重复十次,时间为"+realtime+"毫秒");

    realtime = 0;

    for(int j=0;j<10;j++)

{

for(int i=0;i<10000;i++)

{

TestData[i]=StdRandom.uniform(1000);

TestData_1[i] = TestData[i];

}

starttime =  System.currentTimeMillis();

RQ.sort(TestData_1);

endtime  =  System.currentTimeMillis();

realtime += (endtime - starttime);

System.out.println(endtime - starttime+"ms");

}

    realtime /= 10;

    System.out.println("随机快速排序实现,排序10000个数据,重复十次,时间为"+realtime+"毫秒");

    for(int j=0;j<10;j++)

{

for(int i=0;i<10000;i++)

{

TestData[i]=StdRandom.uniform(1000);

TestData_1[i] = TestData[i];

}

starttime =  System.currentTimeMillis();

QD3P.sort(TestData_1);

endtime  =  System.currentTimeMillis();

realtime += (endtime - starttime);

System.out.println(endtime - starttime+"ms");

}

    realtime /= 10;

 

    System.out.println("三向切分的快排实现,排序10000个数据,重复十次,时间为"+realtime+"毫秒");

}

}

  1. 实验运行结果截图以及数据统计

 

 

 

 

Comparison of running time of sorting algorithms (in Micro Seconds)

 

1

2

3

4

5

6

7

8

9

10

Average

IS

181

188

97

106

118

99

109

99

99

97

129

TDM

4

3

8

12

6

4

5

2

2

1

4

BUM

10

4

3

2

8

7

11

5

2

3

5

RQ

10

3

3

3

4

4

4

3

3

8

4

QD3P

5

7

6

7

11

5

4

5

3

3

6

Comparison of space usage of sorting algorithms (in Kilo Bytes)

 

1

2

3

4

5

6

7

8

9

10

Average

IS

0

0

0

0

0

0

0

0

0

0

0

TDM

10

10

10

10

10

10

10

10

10

10

10

BUM

10

10

10

10

10

10

10

10

10

10

10

RQ

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

QD3P

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

0.013

  1. 回答实验问题

1. Which sort worked best on data in constant or increasing order (i.e., already sorted data)? Why do you think this sort worked best?

回答:插入排序,因为此时,插入排序每次只要比较一次就能确定每一个元素的位置

  1. Did the same sort do well on the case of mostly sorted data? Why or why not?

回答:不会的,因为初始数据基本有序的情况对各种排序的影响很大,比如快排的时候,初始有序的时候就变成N2的算法

  1. In general, did the ordering of the incoming data affect the performance of the sorting algorithms? Please answer this question by referencing specific data from your table to support your answer.

肯定影响的,初始状况对于每一种排序的影响是巨大的,比如我使用均匀分布的十个数据,但是总数据量有10000的时候,三向切分需要6ms,而快排此时就需要33ms,原因是快排处理大量重复数据的时候是非常吃力的

  1. Which sort did best on the shorter (i.e., n = 1,000) data sets? Did the same one do better on the longer (i.e., n = 10,000) data sets? Why or why not? Please use specific data from your table to support your answer.

1000的时候RQ在我的算法中表现的最好,而10000的时候,数据量重复少的时候是RQ,重复多则是QD3P。比如:总数据量有10000的时候,三向切分需要6ms,而快排此时就需要33ms

  1. In general, which sort did better? Give a hypothesis as to why the difference in performance exists.

当然是QD3P,此时他的空间复杂度是lgN,而且也能处理大量重复数据的情况, 时间复杂度介于NlgNN2之间,综合来看比RQ胜任更多的情况

6. Are there results in your table that seem to be inconsistent? (e.g., If I get run times for a sort that look like this {1.3, 1.5, 1.6, 7.0, 1.2, 1.6, 1.4, 1.8, 2.0, 1.5] the 7.0 entry is not consistent with the rest). Why do you think this happened?

对于数据突然出现的偶然性情况,我认为应该是初始化随机数的时候造成了一些偶然情况的发生,使得初始的排序出现了某种比较差的情况

posted @ 2021-01-22 23:22  coolwx  阅读(426)  评论(0编辑  收藏  举报