排序算法 Java實現代碼
JAVA下面的 堆排序 冒泡排序法 選擇排序法 快速排序法 插入排序法 折半插入排序法 希爾排序法 歸并排序法
/*
@param <T> */ public class Sort<T extends Comparable<T>> { //交換索引i和索引j的值 private void swap(T[] data,int i,int j){
T tmp; tmp = data[i]; data[i] = data[j]; data[j] = tmp;
}
//-----堆排序 時間復雜度O(nlogn)----- public void heapSort(T[] data) {
int arrayLength = data.length; // 循環建堆 for (int i = 0; i < arrayLength - 1; i++) { // 建堆 builMaxdHeap(data, arrayLength - 1 - i); // 交換堆頂和最后一個元素 swap(data, 0, arrayLength - 1 - i); //System.out.println(java.util.Arrays.toString(data)); }
}
// 對data數組從0到lastIndex建大頂堆 private void builMaxdHeap(T[] data, int lastIndex) {
// 從lastIndex處節點(最后一個節點)的父節點開始 for (int i = (lastIndex - 1) / 2; i >= 0; i--) { // k保存當前正在判斷的節點 int k = i; // 如果當前k節點的子節點存在 while (k * 2 + 1 <= lastIndex) { // k節點的左子節點的索引 int biggerIndex = 2 * k + 1; // 如果biggerIndex小于lastIndex,即biggerIndex + 1 // 代表的k節點的右子節點存在 if (biggerIndex < lastIndex) { // 如果右子節點的值較大 if (data[biggerIndex].compareTo(data[biggerIndex + 1]) < 0) { // biggerIndex總是記錄較大子節點的索引 biggerIndex++; } } // 如果k節點的值小于其較大子節點的值 if (data[k].compareTo(data[biggerIndex]) < 0) { // 交換它們 swap(data, k, biggerIndex); // 將biggerIndex賦給k,開始while循環的下一次循環, // 重新保證k節點的值大于其左、右子節點的值。 k = biggerIndex; } else { break; } } }
}
//-----冒泡排序法 時間復雜度O(n^2)----- public void bubbleSort(T[] data){
int i,j; for(i=0;i<data.length-1;i++){ for(j=0;j<data.length-i-1;j++){ //排序之前[9, -16*, 21, 23, -30, -49, 21*, 30, 30] //排序之后[-49, -30, -16*, 9, 21, 21*, 23, 30, 30] if(data[j].compareTo(data[j+1]) > 0){ swap(data,j+1,j); } } }
}
//-----選擇排序法 時間復雜度O(n^2)----- public void selectSort(T[] data){
int i,j; for(i=0;i<data.length-1;i++){ for(j=i+1;j<data.length;j++){ //排序之前[9, -16*, 21, 23, -30, -49, 21*, 30, 30] //排序之后[-49, -30, -16*, 9, 21, 21*, 23, 30, 30] if (data[i].compareTo(data[j]) > 0){ swap(data,i,j); } } }
}
//-----快速排序法 時間復雜度為O(log2n)----- public void quickSort(T[] data){
subQuickSort(data,0,data.length-1);
}
private void subQuickSort(T[] data,int start,int end){
if( start < end ){ //以第一個元素作為分界值 T base = data[start]; //i從左邊開始搜索大于分界值元素的索引 int i = start; //j從右邊開始搜索小于分界值元素的索引 int j = end + 1; //排序之前[9, -16*, 21, 23, -30, -49, 21*, 30, 30] //排序之后[-30, -16*, -49, 9, 21*, 21, 23, 30, 30] while(true){ //左邊跳過比base小的元素 while(i < end && data[++i].compareTo(base) <= 0); //右邊跳過比base大的元素 while(j > start && data[--j].compareTo(base) >= 0); if(j > i){ swap(data,i,j); }else{ break; } } //將分界值還原 swap(data,start,j); //遞歸左邊序列 subQuickSort(data,start,j-1); //遞歸右邊序列 subQuickSort(data,j+1,end); // System.out.println( Arrays.toString(data) ); }
}
//-----插入排序法 時間復雜度O(n^2)----- public void insertSort(T[] data){
int arrayLength = data.length; for(int i=1;i<arrayLength;i++){ //當整體后移時保證data[i]的值不會丟失 T tmp = data[i]; //i索引處的值已經比前面所有值都大,表明已經有序,無需插入 //i-1處索引之前的數值已經有序,i-1處索引處元素的值也是最大值 if(data[i].compareTo(data[i-1]) < 0){ int j = i-1; //整體后移一個 while(j>=0 && data[j].compareTo(tmp) > 0){ data[j+1] = data[j]; j--; } data[j+1] = tmp; // System.out.println( Arrays.toString(data) ); } }
}
//-----折半插入排序法 時間復雜度----- public void binaryInsertSort(T[] data) {
int arrayLength = data.length; for (int i = 1; i < arrayLength; i++) { if (data[i - 1].compareTo(data[i]) > 0) { // 緩存i處的元素值 T tmp = data[i]; // 記錄搜索范圍的左邊界 int low = 0; // 記錄搜索范圍的右邊界 int high = i - 1; while (high >= low) { // 記錄中間位置 int mid = (high + low) / 2; // 比較中間位置數據和i處數據大小,以縮小搜索范圍 if (tmp.compareTo(data[mid]) > 0) { low = mid + 1; } else { high = mid - 1; } } // 將low~i處數據整體向后移動1位 for (int j = i; j > low; j--) { data[j] = data[j - 1]; } data[low] = tmp; } //System.out.println( Arrays.toString(data) ); }
}
//-----希爾排序法 時間復雜度O(nlogn)O(n^2)具體看h的值----- public void shellSort(T[] data){
int arrayLength = data.length; //h保存可變增量 int h = 1; while(h<=arrayLength/3){ h = h * 3 + 1; //System.out.println("h="+h); } while(h > 0){ //System.out.println(Arrays.toString( data )+"h="+h); for(int i=h;i<arrayLength;i++){ //當整體后移時,保證data[i]的值不丟失 T tmp = data[i]; //i索引處的值已經比前面所有的值大 //(i-1索引之前的值已經有序的,i-1索引處元素的值就是最大值) if(data[i].compareTo(data[i-h]) < 0){ int j = i-h; //整體后移一格 while(j>=0 && data[j].compareTo(tmp) > 0){ data[j+h] = data[j]; j-=h; } //最后將tmp值插入合適的位置 data[j+h] = tmp; } } h = (h-1)/3; }
}
//-----歸并排序法 時間復雜度為O(nlog2n)----- public void mergeSort(T[] data){
subMergeSort(data,0,data.length-1);
}
private void subMergeSort(T[] data,int left,int right){
if(right > left){ //找出中間索引 //System.out.println( Arrays.toString(data) ); int center = (left + right)/2; //對左邊數組進行遞歸 subMergeSort(data,left,center); //對右邊數組進行遞歸 subMergeSort(data,center+1,right); //合并 merge(data,left,center,right); }
}
@SuppressWarnings("unchecked") private void merge(T[] data, int left, int center, int right) {
Object[] tmpArr = new Object[data.length]; int mid = center + 1; // third記錄中間處索引 int third = left; int tmp = left; while (left <= center && mid <= right) { // 從兩個數組中取出最小的放入中間數組 if (data[left].compareTo(data[mid]) <= 0) { tmpArr[third++] = data[left++]; } else { tmpArr[third++] = data[mid++]; } } // 剩余部分依次放入中間數組 while (mid <= right) { tmpArr[third++] = data[mid++]; } while (left <= center) { tmpArr[third++] = data[left++]; } // 將中間數組的內容復制拷回原數組 // (原left~right范圍內德內容被復制回原數組) while (tmp <= right) { data[tmp] = (T) tmpArr[tmp++]; }
}
/*public static void main(String[] args){
DataWarp[] dataWarp = {
new DataWarp(9,""),
new DataWarp(-16,"*"),
new DataWarp(21,""),
new DataWarp(23,""),
new DataWarp(-30,""),
new DataWarp(-49,""),
new DataWarp(21,"*"),
new DataWarp(30,""),
new DataWarp(56,""),
new DataWarp(40,""),
new DataWarp(430,""),
new DataWarp(-67,""),
new DataWarp(56,""),
new DataWarp(-87,""),
new DataWarp(26,""),
new DataWarp(92,""),
new DataWarp(30,"")
};
DataWarp[] dataWarp2 = {
new DataWarp(9,""),
new DataWarp(-16,"*"),
new DataWarp(21,""),
new DataWarp(23,""),
new DataWarp(-30,""),
new DataWarp(-49,""),
new DataWarp(21,"*"),
new DataWarp(30,""),
new DataWarp(56,""),
new DataWarp(40,""),
new DataWarp(430,""),
new DataWarp(-67,""),
new DataWarp(56,""),
new DataWarp(-87,""),
new DataWarp(26,""),
new DataWarp(92,""),
new DataWarp(30,"")
};
System.out.println( "排序之前" + Arrays.toString(dataWarp) );
Sort<DataWarp> sort = new Sort<DataWarp>();
sort.mergeSort(dataWarp);
sort.shellSort(dataWarp2);
System.out.println( "排序之后" + Arrays.toString(dataWarp) );
System.out.println( "排序之后" + Arrays.toString(dataWarp2) );
}*/
}</pre>