Java数据结构和算法 第二版 课后习题第三章

习题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);
}

 

原文地址:https://www.cnblogs.com/zengy/p/4530338.html