(第9讲)高级排序

1、希尔排序:将增量应用到插入排序,然后逐渐缩小增量。  N-增量排序表示每个n个元素进行排序。常用的今个序列是由递归表达式h = 3*h+1生成的,h的初值是1。

(一个容纳了1000个数据项的数组,对他进行希尔排序可以是间隔序列为364,12,1,40,13,4,最后是1的增量排序)

package com.seven;

public class ShellSort {

         publicstatic void main(String[] args) {

                   intmax = 10;

                   Array3a = new Array3(max);

                   for(int i = 0; i < max; i++) {

                            inttemp = (int) (Math.random() * 99);

                            a.insert(temp);

                   }

                   a.display();

                   a.shellSort();

                   a.display();

         }

}

class Array3 {

         privateint[] a;

         privateint curlen;

         publicArray3(int max) {

                   a= new int[max];

                   curlen= 0;

         }

         publicvoid insert(int value) {

                   a[curlen++]= value;

         }

         publicvoid display() {

                   for(int i = 0; i < curlen; i++) {

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

                   }

                   System.out.println();

         }

         publicvoid shellSort() {

                   inth = 1;

                   while(h <= curlen / 3) {

                            h= h * 3 + 1;

                   }

                   while(h > 0) {// 减少h,直到h=1

                            //插入排序

                            for(int i = h; i < curlen; i++) {

                                     intvalue = a[i];

                                     intvalueIndex = i;

                                     while(valueIndex > h - 1 && a[valueIndex - h] >= value) {

                                               a[valueIndex]= a[valueIndex - h];// 大的右移

                                               valueIndex-= h;

                                     }

                                     a[valueIndex]= value;

                            }

                            h= (h - 1) / 3;

                   }

         }

}

结果是:5 22 76 70 65 23 92 28 97 17

5 17 22 23 28 65 70 76 92 97

2、划分数组:就是把数组分为两个子数组,使所有关键字大于(等于)特定值的数据项(等于)在一组,使所有关键字小于(等于)特定值的数据项(等于)在另外一组。如果在划分的过程中,有关键字和枢纽相等,依然交换。

package com.seven;

public class Partition {

         publicstatic void main(String[] args) {

                   intmax = 10;

                   Array1a = new Array1(max);

                   for(int i = 0; i < max; i++) {

                            inttemp = (int) (Math.random() * 199);

                            a.insert(temp);

                   }

                   a.display();

                   intpivot = 99;     

                   System.out.print("Pivotis " + pivot);

                   intb = a.partition(0, max-1, pivot);

                   System.out.println(",Partition is at index " + b);

                   a.display();

         }

}

class Array1{

         privateint[] a;

         privateint curlen;

         publicArray1(int max){

                   a= new int[max];

                   curlen= 0;

         }

         publicvoid insert(int value){              a[curlen++]= value; }

         publicvoid display(){

                   for(inti=0;i<curlen;i++){System.out.print(a[i]+" ");               }

                   System.out.println();

         }

         publicint partition(int left, int right,int pivot){

                   intleftPar = left-1;

                   intrightPar = right+1;

                   while(true){

                            while(leftPar<right&& a[++leftPar]<pivot )

                                     ;

                            while(left<rightPar&& a[--rightPar]>pivot )

                                     ;

                            if(leftPar>=rightPar){                                    break;

                            }else{                                    swap(leftPar,rightPar);                      }

                   }

                   returnleftPar;

         }

         publicvoid swap(int index1,int index2){

                   inttemp = a[index1];

                   a[index1]= a[index2];

                   a[index2]=temp;

         }

}结果是:

127 9 22 169 95 93 98 110 161 137 

Pivot is 99, Partition is at index 5

98 9 22 93 95 169 127 110 161 137 

3、快速排序:先划分数组(先划分原始数组,然后划分结果中的子数组),然后递归的调用自身,对划分得到的两个子数组进行快速排序。只含有一个数据项的子数组被认定为已经有序,这一点可以作为快速排序算法的基值条件(终止条件)。

在快速排序的简单版本中,总是由子数组的最右端的数据项作为枢纽,但是枢纽也可以是数组中任意的数据项。

/**

 * 快速排序:采用数组最右边的作为枢纽

 */

package com.seven;

public class QuickSort1 {

         publicstatic void main(String[] args) {

                    int maxSize = 16;       

               ArrayIns arr;

               arr = new ArrayIns(maxSize);

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

                  {                       

                  long n =(int)(java.lang.Math.random()*99);

                  arr.insert(n);

                  }

               arr.display();             

               arr.quickSort();                arr.display();        }}

class ArrayIns

{

private long[] theArray;          // ref to array theArray

private int nElems;               // number of data items

//--------------------------------------------------------------

public ArrayIns(int max)          // constructor

   {

  theArray = new long[max];      //create the array

  nElems = 0;                    //no items yet

   }

//--------------------------------------------------------------

public void insert(long value)    // put element into array

   {

  theArray[nElems] = value;      //insert it

  nElems++;                      //increment size

   }

//--------------------------------------------------------------

public void display()             // displays array contents

   {

  System.out.print("A=");

  for(int j=0; j<nElems; j++)   // for each element,

     System.out.print(theArray[j] + " ");  // display it

  System.out.println("");

   }

//--------------------------------------------------------------

public void quickSort()   {  recQuickSort(0, nElems-1);   }

//--------------------------------------------------------------

public void recQuickSort(int left, intright)

   {

  if(right-left <= 0)     

      return;  

  else          {

     long pivot = theArray[right];    

     int partition = partitionIt(left, right, pivot);

     recQuickSort(left, partition-1);  // sort left side

     recQuickSort(partition+1, right); // sort right side

     }

  } 

//--------------------------------------------------------------

 public int partitionIt(int left, int right,long pivot)

    {

   int leftPtr = left-1;           //left    (after ++)

   int rightPtr = right;           //right-1 (after --)

   while(true) {

      while( theArray[++leftPtr] < pivot )

         ; 

      while(rightPtr > 0 && theArray[--rightPtr] > pivot)

         ;

      if(leftPtr >= rightPtr)           break;             

      else       swap(leftPtr,rightPtr);   

   }

   swap(leftPtr, right);   

   return leftPtr;               

   } 

//--------------------------------------------------------------

public void swap(int dex1, int dex2)  // swap two elements

   {

  long temp = theArray[dex1];       // A into temp

  theArray[dex1] = theArray[dex2];  // B into A

  theArray[dex2] = temp;            // temp into B

   }

}

结果是:A=97 86 82 53 86 73 2 35 96 59 1 36 33 9 1 90

A=1 1 2 9 33 35 36 53 59 73 82 86 86 90 9697

4、改进快速排序:采用中值划分(三数据项取中)的作为枢纽,对小于等于三个的数据项采用手动排序

package com.seven;

public class QuickSort2 {

         publicstatic void main(String[] args) {

                    int maxSize = 16;             // array size

               ArrayIns2 arr;                 // reference to array

               arr = new ArrayIns2(maxSize);  // create the array

 

               for(int j=0; j<maxSize; j++)  // fill array with

                  {                          // random numbers

                  long n =(int)(java.lang.Math.random()*99);

                  arr.insert(n);

                  }

               arr.display();                // display items

               arr.quickSort();              // quicksort them

               arr.display();   

 

         }

 

}

class ArrayIns2

{private long[] theArray;          // ref to array theArray

private int nElems;               // number of data items

//--------------------------------------------------------------

public ArrayIns2(int max)          // constructor

   {

  theArray = new long[max];      //create the array

  nElems = 0;                    //no items yet

   }

//--------------------------------------------------------------

public void insert(long value)    // put element into array

   {

  theArray[nElems] = value;      //insert it

  nElems++;                      //increment size

   }

//--------------------------------------------------------------

public void display()             // displays array contents

   {

  System.out.print("A=");

  for(int j=0; j<nElems; j++)   // for each element,

     System.out.print(theArray[j] + " ");  // display it

  System.out.println("");

   }

//--------------------------------------------------------------

public void quickSort()

   {

  recQuickSort(0, nElems-1);

   }

//--------------------------------------------------------------

public void recQuickSort(int left, intright)

   {

  int size = right-left+1;

  if(size <= 3)                 // manual sort if small

     manualSort(left, right);

  else                           //quicksort if large

     {

     long median = medianOf3(left, right);

     int partition = partitionIt(left, right, median);

     recQuickSort(left, partition-1);

     recQuickSort(partition+1, right);

     }

   }  // end recQuickSort()

//--------------------------------------------------------------

public long medianOf3(int left, int right)

   {

  int center = (left+right)/2;

                                      // orderleft & center

  if( theArray[left] > theArray[center] )

     swap(left, center);

                                      // orderleft & right

  if( theArray[left] > theArray[right] )

     swap(left, right);

                                      // ordercenter & right

  if( theArray[center] > theArray[right] )

     swap(center, right);

 

  swap(center, right-1);            // put pivot on right

  return theArray[right-1];         // return median value

  }  // end medianOf3()

//--------------------------------------------------------------

public void swap(int dex1, int dex2)  // swap two elements

   {

  long temp = theArray[dex1];       // A into temp

  theArray[dex1] = theArray[dex2];  // B into A

  theArray[dex2] = temp;            // temp into B

  }  // end swap(

//--------------------------------------------------------------

 public int partitionIt(int left, int right,long pivot)

    {

   int leftPtr = left;             //right of first elem

   int rightPtr = right - 1;       //left of pivot

   while(true)

      {

      while( theArray[++leftPtr] < pivot ) // find bigger

         ;                                 //    (nop)

      while( theArray[--rightPtr] > pivot ) // find smaller

         ;                                  //    (nop)

      if(leftPtr >= rightPtr)      //if pointers cross,

         break;                    //    partition done

      else                         //not crossed, so

         swap(leftPtr, rightPtr);  // swapelements

      }  // end while(true)

   swap(leftPtr, right-1);         //restore pivot

   return leftPtr;                 //return pivot location

   }  // end partitionIt()

//--------------------------------------------------------------

public void manualSort(int left, int right)

   {

  int size = right-left+1;

  if(size <= 1)

     return;         // no sortnecessary

  if(size == 2)

     {               // 2-sort left andright

     if( theArray[left] > theArray[right] )

        swap(left, right);

     return;

     }

  else               // size is 3

     {               // 3-sort left,center, & right

     if( theArray[left] > theArray[right-1] )

        swap(left, right-1);               // left, center

     if( theArray[left] > theArray[right] )

        swap(left, right);                 // left, right

     if( theArray[right-1] > theArray[right] )

        swap(right-1, right);              // center, right

     }

   }

}

结果是:A=21 38 41 74 31 0 61 85 76 47 24 80 35 39 48 54

A=0 21 24 31 35 38 39 41 47 48 54 61 74 7680 85

5、改进快速排序::采用中值划分(三数据项取中)的作为枢纽,对小于等于10个的数据项采用插入排序

package com.seven;

public class QuickSort3 {

         publicstatic void main(String[] args) {

                   intmaxSize = 16;             // array size

               ArrayIns3 arr;                 // reference to array

               arr = new ArrayIns3(maxSize);  // create the array

 

               for(int j=0; j<maxSize; j++)  // fill array with

                  {                          // random numbers

                  long n = (int)(java.lang.Math.random()*99);

                  arr.insert(n);

                  }

               arr.display();                // display items

               arr.quickSort();              // quicksort them

               arr.display(); 

         }}

class ArrayIns3

{

private long[] theArray;          // ref to array theArray

private int nElems;               // number of data items

//--------------------------------------------------------------

public ArrayIns3(int max)          // constructor

   {

  theArray = new long[max];      //create the array

   nElems = 0;                    // no items yet

   }

//--------------------------------------------------------------

public void insert(long value)    // put element into array

   {

  theArray[nElems] = value;      //insert it

  nElems++;                      // increment size

   }

//--------------------------------------------------------------

public void display()             // displays array contents

   {

  System.out.print("A=");

  for(int j=0; j<nElems; j++)   // for each element,

     System.out.print(theArray[j] + " ");  // display it

  System.out.println("");

   }

//--------------------------------------------------------------

public void quickSort()

   {

  recQuickSort(0, nElems-1);

   //insertionSort(0, nElems-1); // the other option

   }

//--------------------------------------------------------------

public void recQuickSort(int left, intright)

   {

  int size = right-left+1;

  if(size < 10)                  // insertion sort if small

     insertionSort(left, right);

  else                            //quicksort if large

     {

     long median = medianOf3(left, right);

     int partition = partitionIt(left, right, median);

     recQuickSort(left, partition-1);

     recQuickSort(partition+1, right);

     }

   }  // end recQuickSort()

//--------------------------------------------------------------

public long medianOf3(int left, int right)

   {

  int center = (left+right)/2;

                                    // orderleft & center

  if( theArray[left] > theArray[center] )

     swap(left, center);

                                    // orderleft & right

  if( theArray[left] > theArray[right] )

     swap(left, right);

                                    // ordercenter & right

  if( theArray[center] > theArray[right] )

     swap(center, right);

 

  swap(center, right-1);          // put pivot on right

  return theArray[right-1];       // return median value

  }  // end medianOf3()

//--------------------------------------------------------------

public void swap(int dex1, int dex2)  // swap two elements

   {

  long temp = theArray[dex1];       // A into temp

  theArray[dex1] = theArray[dex2];  // B into A

  theArray[dex2] = temp;            // temp into B

  }  // end swap(

//--------------------------------------------------------------

 public int partitionIt(int left, int right,long pivot)

    {

   int leftPtr = left;             //right of first elem

   int rightPtr = right - 1;       //left of pivot

   while(true)

      {

      while( theArray[++leftPtr] < pivot ) // find bigger

         ;                                 // (nop)

      while( theArray[--rightPtr] > pivot ) // find smaller

         ;                                 // (nop)

      if(leftPtr >= rightPtr)      //if pointers cross,

         break;                    //    partition done

      else                         //not crossed, so

         swap(leftPtr, rightPtr);  // swapelements

      }  // end while(true)

   swap(leftPtr, right-1);         // restore pivot

   return leftPtr;                 //return pivot location

   }  // end partitionIt()

//--------------------------------------------------------------

public void insertionSort(int left, intright)

   {

  int in, out;

  for(out=left+1; out<=right; out++)

     {

     long temp = theArray[out];  

     in = out;                     

                                   

     while(in>left && theArray[in-1] >= temp)

        {  theArray[in] = theArray[in-1];// shift item to right

        --in;        

        }

     theArray[in] = temp; 

     }    } 

}结果是:A=86 39 50 92 7217 73 89 16 9 3 25 24 81 71 48

A=3 9 16 17 24 25 39 48 50 71 72 73 81 8689 92

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值