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