如下程序均將數據封裝於DataWrap數據包裝類中,以下所示:數組
class DataWrap implements Comparable<DataWrap> { int data; String flag; public DataWrap(int data,String flag) { this.data = data; this.flag = flag; } //重寫compareTo方法 public int compareTo(DataWrap other) { return this.data > other.data ? 1 : (this.data == other.data ? 0 : -1); } public String toString() { return this.data + this.flag; } }
1、選擇排序ui
一、直接選擇排序this
數組分紅有序區和無序區,初始時整個數組都是無序區,而後每次從無序區選一個最小的元素直接放到有序區的最後,直到整個數組變有序區。spa
1 public static void directSelectSort(DataWrap[] dw) 2 { 3 int n = dw.length; 4 for(int i = 0;i < n-1;i++) 5 { 6 int minIndex = i; 7 for(int j = i+1;j < n;j++) 8 { 9 if(dw[minIndex].compareTo(dw[j]) > 0) 10 { 11 minIndex = j; //minIndex爲每趟比較重最小數的索引 12 } 13 } 14 swap(dw,minIndex,i); 15 System.out.println("直接選擇排序中的元素:" + Arrays.toString(dw)); 16 } 17 18 }
二、堆排序code
1)二叉堆排序
二叉堆是徹底二叉樹或者是近似徹底二叉樹。遞歸
父結點的鍵值老是大於或等於(小於或等於)任何一個子節點的鍵值。索引
每一個結點的左子樹和右子樹都是一個二叉堆(都是最大堆或最小堆)。it
當父結點的鍵值老是大於或等於任何一個子節點的鍵值時爲最大堆。當父結點的鍵值老是小於或等於任何一個子節點的鍵值時爲最小堆。io
2)堆的存儲
通常都用數組來表示堆,i結點的父結點下標就爲(i – 1) / 2。它的左右子結點下標分別爲2 * i + 1和2 * i + 2。如第0個結點左右子結點下標分別爲1和2。
3)堆排序原理(以最小堆爲例)
堆排序是先創建一個最小堆,而後第一次將A[0]與A[n - 1]交換,再對A[0…n-2]從新恢復最小堆。第二次將A[0]與A[n – 2]交換,再對A[0,…,n - 3]從新恢復最小堆,重複這樣的操做直到A[0]與A[1]交換。因爲每次都是將最小的數據併入到後面的有序區間,故操做完成後整個數組就有序(爲降序)了。
創建最小堆就是先從最後一個非葉子節點(即n/2-1節點)開始,節點依次往前就行,直到第二個節點。對於每一個節點,先比較其左右節點選出較小的節點,而後將較小的節點與父節點進行比較。若是父節點比最小的子節點還小的話則不須要調整,不然的話將較小的子節點做爲新的父節點,將原先的父節點與其子節點的子節點中較小的進行比較,直到該父節點找到可以插入的位置或者是到達堆的結束。
4)代碼實現
1 public class HeapSort 2 { 3 /** 4 * 從某一節點向下調整大小 5 * @param dw 待排序數據包 6 * @param i 開始向下調整的堆索引 7 * @param n 所調整堆數據的大小 8 */ 9 public static void MinHeapFixDown(DataWrap[] dw,int i,int n) 10 { 11 int j; 12 DataWrap temp; 13 j = 2 * i +1; 14 temp = dw[i]; 15 while(j < n) 16 { 17 if(j+1 < n && dw[j+1].compareTo(dw[j]) < 0) 18 { //找出左右子節點中較小的 19 j++; 20 } 21 if(temp.compareTo(dw[j]) <= 0) 22 { //將父節點與子節點進行比較 23 break; 24 } 25 dw[i] = dw[j]; //將較小的子節點上移 26 i = j; 27 j = 2 * i +1; 28 } 29 dw[i] = temp; 30 } 31 //構建最小堆並進行堆排序 32 public static void heapSort(DataWrap[] dw) 33 { 34 int n = dw.length; 35 //構建最小堆 36 for(int i = n/2-1;i >= 0;i--) 37 { 38 HeapSort.MinHeapFixDown(dw, i, n); 39 } 40 //堆排序 41 for(int i = n-1;i >=1;i--) 42 { 43 swap(dw,0,i); //每次將第n-1,n-2,...1個元素與dw[0]交換後,將最後一個元素從堆中排除 44 MinHeapFixDown(dw, 0, i); //將每次交換後-1的堆從dw[0]開始,調整爲新的最小堆 45 } 46 } 47 48 //交換DataWrap數組中i,j兩數值 49 public static void swap(DataWrap[] dw,int i,int j) 50 { 51 DataWrap temp; 52 temp = dw[i]; 53 dw[i] = dw[j]; 54 dw[j] = temp; 55 } 56 57 public static void main(String[] args) 58 { 59 DataWrap[] dw = {new DataWrap(25,""),new DataWrap(42,""),new DataWrap(36,""),new DataWrap(8,""),new DataWrap(78,""),new DataWrap(99,"")}; 60 System.out.println("待排序數據爲:" + Arrays.toString(dw)); 61 HeapSort.heapSort(dw); 62 System.out.println("排序後數據爲:" + Arrays.toString(dw)); 63 } 64 }
2、交換排序
一、冒泡排序
1.比較相鄰的先後二個數據,若是前面數據大於後面的數據,就將二個數據交換。
2.這樣對數組的第0個數據到N-1個數據進行一次遍歷後,最大的一個數據就「沉」到數組第N-1個位置。
3.N=N-1,若是N不爲0就重複前面二步,不然排序完成。
1 public static void bubbleSort(DataWrap[] dw) 2 { 3 int n = dw.length; 4 boolean flag;//設置標誌位,若發生未交換的狀況,說明已經有序,退出循環便可 5 for(int i = n-1;i > 0 ;i--) 6 { 7 flag = false; 8 for(int j = 0;j < i;j++) 9 { 10 if(dw[j].compareTo(dw[j+1]) > 0) 11 { 12 swap(dw,j+1,j); 13 flag = true; 14 } 15 } 16 if(!flag) 17 { 18 break; 19 } 20 System.out.println("排序中順序:" + Arrays.toString(dw)); 21 } 22 }
二、快速排序
快速選擇排序主要思路是:
「挖坑填數+分治法」,首先令i =L; j = R; 將a[i]挖出造成第一個坑,稱a[i]爲基準數。而後j--由後向前找比基準數小的數,找到後挖出此數填入前一個坑a[i]中,再i++由前
向後找比基準數大的數,找到後也挖出此數填到前一個坑a[j]中。重複進行這種「挖坑填數」直到i==j。再將基準數填入a[i]中,這樣i以前的數都比基準數小,i以後的數都比基準數
大。所以將數組分紅二部分再分別重複上述步驟就完成了排序。
public class QuickSort { static int partition(int[] data, int left, int high) { int midData = data[left]; while (left < high) { while (left < high && midData < data[high]) high--; data[left] = data[high]; while (left < high && midData >= data[left]) left++; data[high] = data[left]; } data[left] = midData; return left; } /** * 快速排序 * * @param data * @param left * @param high */ static void quick_sort(int[] data, int left, int high) { int loc = 0; if (left < high) { loc = partition(data, left, high); quick_sort(data, left, loc - 1); quick_sort(data, loc + 1, high); } } public static void main(String[] args) { int[] data = {6, 2, 4, 8, 5, 9}; quick_sort(data, 0, data.length - 1); System.out.print("排序後數據爲:" + Arrays.toString(data)); } }
3、插入排序
一、直接插入排序
每次將一個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中的適當位置,直到所有記錄插入完成爲止。
public static void directInsertSort(DataWrap[] dw,int n) 2 { 3 for(int i = 1;i < n;i++) 4 { 5 if(dw[i].compareTo(dw[i-1]) < 0) 6 { 7 DataWrap temp = dw[i]; 8 int j; 9 for(j = i-1;j >= 0 && dw[j].compareTo(temp) > 0;j--) 10 { 11 dw[j+1] = dw[j]; 12 } 13 dw[j+1] = temp; 14 } 15 } 16 }
二、希爾排序(Shell排序、縮小增量排序)
先將整個待排元素序列分割成若干個子序列(由相隔某個「增量」的元素組成的)分別進行直接插入排序,而後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。因爲希爾排序是對相隔若干距離的數據進行直接插入排序,所以能夠形象的稱希爾排序爲「跳着插」
public static void directInsertSort(DataWrap[] dw,int n) 2 { 3 for(int i = 1;i < n;i++) 4 { 5 if(dw[i].compareTo(dw[i-1]) < 0) 6 { 7 DataWrap temp = dw[i]; 8 int j; 9 for(j = i-1;j >= 0 && dw[j].compareTo(temp) > 0;j--) 10 { 11 dw[j+1] = dw[j]; 12 } 13 dw[j+1] = temp; 14 } 15 } 16 }
4、歸併排序
當一個數組左邊和右邊都有序時,將兩邊合併就完成了排序,而要使兩邊都有序,則須要用遞歸。先遞歸下去,再合併上來,就是歸併排序。
1 public class MergeSort 2 { 3 4 public static void mergeSort(int[] data) 5 { 6 int n = data.length; 7 sort(data, 0, n-1);//歸併排序 8 } 9 10 public static void sort(int[] data,int left,int right) 11 { 12 if(left <right) 13 { 14 int center = (left + right)/2;//中間索引 15 sort(data, left, center);//堆左邊數組進行遞歸 16 sort(data, center+1, right);//堆右邊數組進行遞歸 17 merge(data, left, center, right);//合併 18 } 19 } 20 21 public static void merge(int[] data,int left,int center,int right) 22 { 23 int[] array = new int[data.length];//定義臨時數組 24 int mid = center+1; 25 int k = left;//臨時數組索引 26 int temp = left; 27 while(left <= center && mid <= right) 28 { 29 if(data[left] < data[mid]) 30 array[k++] = data[left++]; 31 else 32 array[k++] = data[mid++]; 33 } 34 while(left <= center) 35 array[k++] = data[left++]; 36 while(mid <= right) 37 array[k++] = data[mid++]; 38 while(temp <= right) 39 data[temp] = array[temp++]; 40 } 41 42 public static void main(String[] args) 43 { 44 int[] data = {2,27,56,8,24,12,99,0,56}; 45 MergeSort.mergeSort(data); 46 for(int i:data) 47 { 48 System.out.print(i + ","); 49 } 50 } 51 }