《Java数据结构和算法》第二版 Robert lafore 编程作业 第三章

《Java数据结构和算法》第二版 Robert lafore  编程作业 第三章

参考 https://blog.csdn.net/zhch152/article/details/7906162

  1. 3.1 bubbleSort.java程序(清单3.1)和BubbleSort专题applet中,in索引变量都是从左到
              右移动的,直到找到最大数据项并把它移动到右边的out变量外。修改bubbleSort()方法,
              使它成为双向移动的。这样,in索引先像以前一样,将最大的数据项从左移到右,当它到
              达out变量位置时,它掉头并把最小的数据项从右移到左。需要两个外部索引变量,一个在
              右边(以前的out变量),另一个在左边。

     //3.1
       public void bubbleSort()
          {
          int left ,right, in;
          for(right =nElems-1,left=0;right>left;right--,left++){
    
             //从左到右选出最大
          for(in= left;in<right;in++){
                com++;//比较次数
                if(a[in]>a[in+1]){
                   swap++;//交换次数
                   swap(in,in+1);
                }
             }
             //从右到左选出最小
             for(in--;in>left;in--){
                com++;
                if(a[in-1]>a[in]){
                   swap++;
                   swap(in,in-1);
                }
             }
          }

    3.2    在isertSort.java程序(清单3.3)中给ArrayIns类加一个median()方法.这个方法将返回
              数组的中间值.(回忆一下,数组中一半数据项比中间值大,一半数据项比中间值小。)

      /**
           * 3.2返回数组的中间值 如果数组长度为奇数 则放回中间值 否则取两个中间值的平均值
           * @return
           */
          public long media(){
             //将数组排序
             this.insertionSort();
             int midIndex =nElems/2;
             if(nElems%2 == 0){
                return nElems==0?0:(a[midIndex]+a[midIndex-1])/2;
             }else{
                return a[midIndex];
             }
    
          }

    3.3    在insertSort.java程序(清单3.3)中增加一个名为noDups()的方法,这个方法从已经有
             序的数组中删掉重复的数据项而不破坏有序性。(可以用insertionSort()方法对数据排序,
             或者也可以简单地用main()方法将数据有序地插入到表中。)一种解决方法是每发现一个重
             复的数据,就从这个位置开始到数组结尾都向前移动一个位置,但这样就导致消耗很长的
             O(N2)的时间级,起码在有很多重复数据项的情况下是这样的。在设计的算法中,不论有多
             少重复数据,要确保数据项最多只能移动一次。这样算法只消耗O(N)数量级的时间。

  2.  /**
           * 3.3删除重复元素(已排序)
           */
          public void noDups(){
             //先循环找出重复元素并设为空
             if(nElems ==0 ) return;
             long lastVal = a[0];
             int newElems = nElems;
             int lastDupIndex = -1;//记录上个重复的索引
             for (int i=1;i< nElems;i++){
                if(a[i] == lastVal){//等于
                   newElems--;
                   a[i]=0;//默认为0
                   if(lastDupIndex == -1){
                      lastDupIndex = i;
                   }
                }else {//大于
                   lastVal = a[i];
                   if(lastDupIndex != -1){
                      a[lastDupIndex] =a[i];
                      a[i]=0;//默认为0
                      lastDupIndex++;
                   }
                }
             }
             nElems =newElems;
          }

    3.4  还有一种简单排序算法是奇偶排序。它的思路是在数组中重复两趟扫描。第一趟扫描选择所有
             的数据项对,a[j]和a[j+1],j是奇数(j=1,3,5,……)。如果它们的关键字的值次序颠倒,就交
             换它们。第二趟扫描对所有的偶数数据项进行同样的操作(j=2,4,6,……)。重复进行这样两趟
             的排序直到数组全部有序。用oddEvenSort()方法替换bubbleSort.java程序(清单3.1)中的
             bubbleSort()方法。确保它可以在不同数据量的排序中运行,还需要算出两趟扫描的次数。奇
             偶排序实际上在多处理器环境中很有用,处理器可以分别同时处理每一个奇数对,然后又同时
             处理偶数对。因为奇数对是彼此独立的,每一对都可以用不同的处理器比较和交换。这样可以非
             常快速地排序。

      //3.4 奇偶排序
          public void oddEventSort(){
            int count=0;
             boolean isChange = true;
             int start = 0;//0 偶交换 1 奇交换
             while (isChange){
                count++;
                isChange = false;
                for(int i= start ;i<nElems-1;i+=2){
                   com++;
                   if(a[i]>a[i+1]){
                      swap++;
                      isChange = true;
                      swap(i,i+1);
                   }
                }
                start = start ==0?1:0;
             }
             System.out.println("count "+count);
    
          }

    3.6    有一个有趣的方法用来删除数组中相同的数据项。插入排序算法中用一个循环嵌套算法,将
             数组中的每一个数据项与其他数据项一一比较。如果要删除相同的数据项,可以这样做(参见第
             2章第2.6小节)。修改insertSort.java中的insertionSort()方法,使它可以在排序过程中
             删除相同的数据项。方法如下:当找到一个重复数据项的时候,通常用一个小于任何值的关键值
             来改写这个相同数据项(如果所有值都是正数,则可取-1)。于是,一般的插入排序算法就会像
             处理其他数据项一样,来处理这个修改了关键值的数据项,把它移到下标为0的位置。从现在开
             始,算法可以忽略这个数据项。下一个相同的数据项将被移到下标为1的位置,依此类推。排序
             完成后,所有相同的数据项(现在关键值为-1)都在数组的开头部分。可以改变数组的容量并
             把需要的数据前移动数组下标为0的位置。

    /**
           * 3.6 插入排序并移除重复数据
           */
          public void insertSortedNoDup() {
             int in,out;
             int dupNum = 0;
    
             for(out =0;out <nElems;out++){
                long temp = a[out];
                for(in =out-1;in>=0;in--){
                   com++;
                   if(temp > a[in]){
                      break;
                   }
                   else if(temp == a[in]){
                      for(int index = in;index >dupNum;index--){
                         a[index] =a[index -1];
                      }
                      dupNum++;
                      a[dupNum-1]=-1;
                      break;
                   }else {
                      swap++;
                      a[in + 1] = a[in];
                   }
                }
                a[in+1] = temp;
             }
             System.out.println("dupSize" +dupNum);
    
             for (int i=dupNum;i<nElems;i++){
                a[i-dupNum] = a[i];
             }
             nElems -=dupNum;
          }

猜你喜欢

转载自blog.csdn.net/sunforlife/article/details/81811508