习题1、bubbleSort.java程序(清单3.1)和BubbleSort专题applet中,in索引变量都是从左到右移动的,直到找到最大数据项并把它移动到右边的out变量外。修改bubbleSort()方法,使它成为双向移动的。这样,in索引先像以前一样,将最大的数据项从左移到右,当它到达out变量位置时,它掉头并把最小的数据项从右移到左。需要两个外部索引变量,一个在右边(以前的out变量),另一个在左边。
public static void bubbleSort(int nElem,int [] source){
int leftOut=0,rightOut=nElem-1,in;
while(leftOut<=rightOut){
for(in = leftOut;in<rightOut;in++){
if(source[in]>source[in+1])
swap(source,in,in+1);
}
for(in=rightOut-1;in>leftOut;in--){
if(source[in]<source[in-1])
swap(source, in, in-1);
}
++leftOut;
--rightOut;
for(int i=0;i<nElem;i++)
System.out.print(source[i]+",");
System.out.println(" ");
}
习题3、在insertSort.java程序(清单3.3)中增加一个名为noDups()的方法,这个方法从已经有序的数组中删掉重复的数据项而不破坏有序性。(可以用insertionSort()方法对数据排序,或者也可以简单地用main()方法将数据有序地插入到表中。)一种解决方法是每发现一个重复的数据,就从这个位置开始到数组结尾都向前移动一个位置,但这样就导致消耗很长的 O(N2)的时间级,起码在有很多重复数据项的情况下是这样的。在设计的算法中,不论有多少重复数据,要确保数据项最多只能移动一次。这样算法只消耗O(N)数量级的时间。
public static int[] noDub(int[] source,int nElem){
int[] result = new int[nElem];
int j=0;
for(int i=0;i<nElem-1;i++){
if(source[i]!=source[i+1]){
result[j] = source[i];
++j;
} //如果两个元素相等,则不做任何事,只是等待下一步将索引指向下一个,即插入的元素是相等的那几个元素中的最后一个元素
}
result[j]=source[nElem-1]; //最后一个元素在for循环中并没有进行处理,无论它与前面一个数相等或者不相等都应该被插入。
return result;
}
习题4、还有一种简单排序算法是奇偶排序。它的思路是在数组中重复两趟扫描。第一趟扫描选择所有 的数据项对,a[j]和a[j+1],j是奇数(j=1,3,5,……)。如果它们的关键字的值次序颠倒,就交 换它们。第二趟扫描对所有的偶数数据项进行同样的操作(j=2,4,6,……)。重复进行这样两趟 的排序直到数组全部有序。用oddEvenSort()方法替换bubbleSort.java程序(清单3.1)中的 bubbleSort()方法。确保它可以在不同数据量的排序中运行,还需要算出两趟扫描的次数。奇 偶排序实际上在多处理器环境中很有用,处理器可以分别同时处理每一个奇数对,然后又同时 处理偶数对。因为奇数对是彼此独立的,每一对都可以用不同的处理器比较和交换。这样可以非 常快速地排序。
public static void oddEvenSort(int[] source,int nElem){
boolean changed = true;
while(changed){
changed = false;
for(int i=0;i<nElem;i=i+2){
if(a[i] > a[i+2]){
swap(i,i+2);
changed = true;
}
}
for(int i=1;i<nElem;i=i+2){
if(a[i] > a[i+2]){
swap(i,i+2);
changed = true;
}
}
}
}
习题5、修改insertSort.java程序(清单3.3)中的insertionSort()方法,使它可以计算排序过 程中复制和比较的次数并显示出总数。为计算比较的次数,要把内层while循环的两个条件分开。用这个程序测量各种数量的逆序数据排序的复制和比较次数。结果满足O(N2)吗?与已经基本有 序的数据(仅有很少的数据无序)的情况一样吗?从对基本有序数据排序的表现中可得出关于这 个算法效率的什么结论?
public static void insertionSort(int[] source,int nElem){
int out,in;
int compare=0,copy=0,temp;
for(out=1;out<nElem;out++){
temp = source[out];
for(in = out;in>0;in--){
if(source[in-1]>temp){
source[in] = source[in-1];
++copy;
++compare;
}
else{
++compare;
break;
}
}
source[in] = temp;
}
for(int i=0;i<source.length;i++)
System.out.print(source[i]+",");
System.out.println(" ");
System.out.println("compaer = "+compare+"copy = "+copy);
}