选择排序
__setattr__
插入排序
super().__setattr__
这是我的比较时间码。
public class Selection implements Sortable {
public void sort(Comparable[] a){
for(int i=0;i<a.length;i++){
int min=i;
for(int j=i+1;j<a.length;j++){
if(less(a[j],a[min])){
min = j;
}
}
exch(a,i,min);
}
}
private boolean less(Comparable v,Comparable w){
return v.compareTo(w) <0;
}
private void exch(Comparable[] a,int i,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
主要代码
public class Insertion implements Sortable{
public void sort(Comparable[] a){
for(int i=1;i<a.length;i++){
for(int j=i;j>0;j--){
if(less(a[j],a[j-1])){
exch(a,j,j-1);
}
}
}
}
}
结果让我感到惊讶。我已经运行了很多次。我的选择排序总是比插入排序快。我也多次检查我的代码。我不知道在哪里有问题。
public class SortCompare {
public static double time(Sortable s,Comparable[] a){
Stopwatch timer = new Stopwatch();
s.sort(a);
return timer.elapsedTime();
}
public static double timeRandomInput(Sortable s,int N,int T){
double total = 0.0;
Double[] a = new Double[N];
for (int t=0;t<T;t++){
for(int i=0;i<a.length;i++){
a[i]= StdRandom.uniform()*10; //get a random number
}
total+=time(s,a);
}
return total;
}
}
如果我将数据集更改为10000.Selection alomost比Insertion快1倍。
public class Main {
public static void main(String[] args) {
Selection s = new Selection();
Insertion i = new Insertion();
//ShellSort sh =new ShellSort();
double timeSelection = SortCompare.timeRandomInput(s,2000,100);
double timeInsertion = SortCompare.timeRandomInput(i,2000,100);
//double timeSh = SortCompare.timeRandomInput(sh,2000,100);
System.out.println(timeSelection+" "+timeInsertion);
}
}
我正在阅读这本书algorithm 4th。作者说,在一般情况下,插入排序将比选择排序更快。
答案 0 :(得分:4)
也许是因为Insertion Sort的实现并没有那么好。它可以用&#34;大量的交换&#34;来编写,就像你一样。它通常在教科书中以这种形式出现,但在现实生活中却找不到 - 一个很好的实施方式将会移动到#34;元素(不交换它们)然后仅在该循环结束时将添加的元素戳到新打开的位置(而不是添加元素&#34;遍历&#34;数组)。这节省了大约一半的移动,并且重复访问数组以进行比较,以便每次都获得相同的项目(因此在Java中,还有许多边界检查)。
答案 1 :(得分:1)
理论上,插入排序和选择排序的渐近运行时间为O(n ^ 2)。
所以我不确定你为什么期望一个比另一个快。
此外,您正在测试的数据集非常小。如果你使用更大的数据集,我会期望运行时间相对增长更近。
答案 2 :(得分:0)
我在这里犯了一个愚蠢的错误。
只需更改以下代码即可。
public class Insertion implements Sortable{
public void sort(Comparable[] a){
for(int i=1;i<a.length;i++){
for(int j=i;j>0;j--){
if(less(a[j],a[j-1])){
exch(a,j,j-1);
}
else break;//i forget to add this line...
}
}
}
}