快排:將原始數組分成兩個子數組,第一個子數組中的元素小於或等於某個選定的關鍵字,這個關鍵字就是基準,第二個數組大於這個基準,然後對這兩個數組進行單獨排序,但在排序之前要對每個數組進行反覆的劃分操作,直到劃分到只含有一個元素的數組,這時就把數組分成了單個的元素。
該方法的基本思想是:
1.先從數列中取出一個數作爲基準數。
2.分區過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
3.再對左右區間重複第二步,直到各區間只有一個數。
歸併排序:歸併排序主要是將多個已經排好序的數組組合併成一個排好序的數組,這些子數組必須先排好序,方法是先將數組拆分成一個元素的數組,然後再將他們兩兩合併在一起,然後依次將合併的數組在合併。
堆排序:利用堆的特性,堆頂是最大值或者最小值,每次取得最大值(最小值)變的特別方便。
1、將初始待排序關鍵字序列(a1,a2....an)構建成大頂堆,此堆爲初始的無須區;
2、將堆頂元素a[1]與最後一個元素a[n]交換,此時得到新的無序區(a1,a2,......an-1)和新的有序區(an),且滿足a[1,2...n-1]<=a[n];
3、由於交換後新的堆頂a[1]可能違反堆的性質,因此需要對當前無序區(a1,a2,......an-1)調整爲新堆,然後再次將a[1]與無序區最後一個元素交換,得到新的無序區(a1,a2....an-2)和新的有序區(an-1,an)。不斷重複此過程直到有序區的元素個數爲n-1,則整個排序過程完成。
public class MySort {
public static void main(String [] args) {
int [] array = {10,4,7,5,9,10,40,50,20,8,12,11,28};
int [] temp = new int [array.length];
//Sort.mergeSort(array, 0, array.length-1, temp);
//Sort.quickSort(array, 0, array.length-1);
//Sort.insertSort(array);
//Sort.selectionSort(array);
//Sort.bubbleSort(array);
Sort.heapSort(array, array.length);
for(int i=0;i<array.length;i++)
System.out.print(array[i]+" ");
}
}
class Sort{
// 快排
public static void quickSort(int [] array, int first, int last) {
if(first<last) {
int temp = partition(array,first,last);
//System.out.println(temp);
quickSort(array,temp,last-1);
quickSort(array,first,temp-1);
}
}
public static int partition(int [] array,int left, int right) {
int priot = array[left];
int first = left;
int last = right;
while(first<last) {
//System.out.println("first="+first+" last="+last);
while(first<last && array[last]>=priot) {
last--;
}
if(first<last) {
array[first] = array[last];
first++;
}
while(first <last && array[first]<=priot){
first++;
}
if(first<last) {
array[last]=array[first];
last--;
}
}
array[first]=priot;
return first;
}
//歸併排序
//將有序數列a[first...mid]和a[mid...last]合併
public static void mergeArray(int a[],int first, int mid, int last,int temp[]) {
int i = first,j = mid+1;
int m = mid, n=last;
int k=0;
while(i<=m && j<=n) {
if(a[i]<=a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while(i<=m)
temp[k++] = a[i++];
while(j<=n)
temp[k++] = a[j++];
for(i=0;i<k;i++)
a[first+i] = temp[i]; // 把排好序的數組賦值回去給a
}
public static void mergeSort(int a[],int first,int last,int temp[]) {
if(first<last) {
int mid = (first+last)/2;
//將數組分裂
mergeSort(a,first,mid,temp);
mergeSort(a,mid+1,last,temp);
//將數組合並
mergeArray(a,first,mid,last,temp);
}
}
public static void insertSort( int [] a) { //插入排序,每次把最小的插入到前面去
int length = a.length;
for(int i=1;i<length;i++) {
int temp = a[i];
int j=0;
for( j=i; j>0 && temp<a[j-1];j--) { //把大於temp的值往後移動一位,然後把temp插入到合適的位置
a[j] = a[j-1];
}
a[j] = temp;
}
}
public static void selectionSort(int [] a) { //選擇排序
int length = a.length;
for(int i=0;i<length-1;i++) {
int index = i;
for(int j=i+1;j<length;j++) {
if(a[j]<a[index])
index = j;
}
Sort.swap(a, i, index);
}
}
public static void bubbleSort(int [] a) {
int length = a.length;
for(int i=0;i<length-1;i++) {
for(int j=length-1; j>i; j--) {
if(a[j] < a[j-1])
Sort.swap(a, j, j-1);
}
}
}
public static void swap(int [] a,int i,int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void heapSort(int [] a,int size) {
for(int i=size/2-1;i>=1;i--) {
Sort.moveDown(a, i, size-1); // 首先讓他變成最大堆
}
for(int i= size-1;i>=0;i--) {
Sort.swap(a, 0, i); // 把最大的值放到數組最後一位
Sort.moveDown(a, 0, i-1); //把數組中最後一位剔除,再進行調整爲最大堆
}
}
public static void moveDown(int [] a,int first,int last) {
int largest = 2*first+1;
while(largest < last) {
if(largest < last && a[largest] < a[largest+1]) //父節點有兩個子節點
largest++;
if(a[first] < a[largest]) {
Sort.swap(a, first, largest);
first = largest;
largest = 2*first+1;
}else {
largest = last+1; //退出循環
}
}
}
}