↵
import com.sun.scenario.effect.Merge;
public class Sort {
private static void swap(int arr[], int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 1. 冒泡排序
// 時間複雜度爲 N^2
// 空間複雜度O(1)
// 穩定排序
public static void bubbleSort(int[] arr, int len) {
/**
* 1>相鄰兩數進行比較,比較一遍後,最後一個數最大。
* 2>進行n-1遍後,排列有序
*/
for (int i = 0; i < len; i++) {
boolean flag = true;
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) { //相鄰兩數進行比較,若前大於後,交換倆數
swap(arr, j, j + 1);
flag = false;
}
}
if (flag)
continue;
}
}
/**
* 2. 插入排序:將數據插入前面已經排好序的隊列中
* 平均時間複雜度爲 N^2
* 空間複雜度O(1)
* 穩定排序
*
* @param arr
* @param length
*/
public static void insertSort(int[] arr, int length) {
int i, j;
for (i = 1; i < length; i++) {
int tmp = arr[i];
for (j = i; j > 0 && arr[j - 1] > tmp; j--) {
arr[j] = arr[j - 1];
}
arr[j] = tmp;
}
}
/**
* 3. 選擇排序:
* 每一趟從待排序的數據元素中選擇最小(或最大)的一個元素作爲首元素,
* 直到所有元素排完爲止。
*/
public static void selectSort(int[] arr, int len) {
for (int i = 0; i < len; i++) {
int min = i;
for (int j = i + 1; j < len; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
if (min != i)// 若min發生改變,進行交換
swap(arr, i, min);
}
}
/**
* 4. 希爾排序:改進版的插入排序
* 步長由長到短分組,進行排序,直到步長爲1爲止
*
* @param arr
* @param len
*/
public static void shellSort(int[] arr, int len) {
for (int gap = len / 2; gap > 0; gap /= 2) {// 間隔量gap
// 下面相當於插入排序(插入排序相當於是間隔量爲1的希爾排序)
for (int i = gap; i < len; i++) {
int tmp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = tmp;
}
}
}
/**
* 5.歸併排序: 拆分 合併
* 時間複雜度: O(NlogN)
* 空間複雜度: 對於數組來說, O(N)
* 穩定性: 穩定排序
*
* @param arr
* @param low
* @param high 數組最後一個的下標
*/
public static void mergeSort(int[] arr, int low, int high) {
if (low < high) {
// 1>拆分
int mid = (low + high) / 2;
// 遞歸解決左右兩邊子問題
mergeSort(arr, low, mid);
mergeSort(arr, mid + 1, high);
// 2>左右歸併
Merge(arr, low, mid, high);
}
}
/**
* <2> 合併
*
* @param arr 數組
* @param low 低下標
* @param mid 中間位置數值下標
* @param high 高下標
*/
public static void Merge(int[] arr, int low, int mid, int high) {
int[] pro = new int[high - low + 1]; // 一個輔助數組
int i = low;
int j = mid + 1;
int index = 0;// 輔助數組索引
// 1>兩個數組從0開始比較,並將小的數放入輔助數組中
while (i <= mid && j <= high) {
if (arr[i] < arr[j])
pro[index++] = arr[i++];
else
pro[index++] = arr[j++];
}
// 2>若;兩個數組個數不同,比較完1>後,個數少的數組會有餘留
while (i <= mid)
pro[index++] = arr[i++];
while (j <= high)
pro[index++] = arr[j++];
// 3>將排序好的輔助數組中的值放入原數組
for (int k = 0; k < index; k++)
arr[k + low] = pro[k];
}
// 6. 堆排序:先建大堆,然後循環刪除堆頂元素
public static void heapSort(int[] arr, int size) {
// 創建大堆
createHeap(arr, size);
// 循環刪除堆頂
for (int i = 0; i < size; i++) {
heapPop(arr, size - i);
}
}
// 堆刪
private static void heapPop(int[] arr, int size) {
if (size <= 1)
return;
swap(arr, 0, size - 1);
adjustDown(arr, size - 1, 0);
}
// 創建最大堆
private static void createHeap(int[] arr, int size) {
if (size <= 1) // 個數爲1的話,直接返回
return;
int parent = (size - 1 - 1) / 2; // 從末尾起第一個非葉子結點
for (int i = parent; i >= 0; i--) {
adjustDown(arr, size, i);
}
}
// 向下調整
private static void adjustDown(int[] arr, int size, int i) {
int parent = i;
int child = 2 * parent + 1;
while (child < size) {
// 比較左右孩子結點大小
if (child + 1 < size && arr[child] < arr[child + 1])
child = child + 1;
// 大孩子與父結點進行比較
if (arr[parent] < arr[child])
swap(arr, child, parent);
// 繼續向下調整
parent = child; // child相當於一個標記,爲與父結點進行交換的孩子的下標
child = 2 * parent + 1;
}
}
// 7. 快速排序
/**
* 時間複雜度: 最壞 O(N ^ 2)(如果數組是逆序的) 平均水平 O(NlogN)
* 不穩定排序
* @param arr
* @param start
* @param end
*/
public static void quickSort(int[] arr, int start, int end) {
int pivot = arr[start];
int left = start;
int right = end;
while (left < right) {
// 先從右邊尋找比基準值小的數
while (left < right && arr[right] > pivot)
right--;
// 左邊開始尋找比基準值大的數
while (left < right && arr[left] < pivot)
left++;
if (left < right)
swap(arr, left, right);
}
// 此時left==right
if (left - 1 > start) quickSort(arr, start, left - 1);
if (right + 1 < end) quickSort(arr, right + 1, end);
}
public static void main(String[] args) {
// int[] arr = {3, 1, 9, 7, 13, 0, 24, 67, 33};
int arr[] = {6, 1, 2, 7, 4, 5, 10, 8};
int len = arr.length;
// insertSort(arr, len);
// bubbleSort(arr, len);
// mergeSort(arr, 0, len - 1);
// shellSort(arr, len);
// selectSort(arr, len);
// heapSort(arr, len);
quickSort(arr, 0, len - 1);
for (int a : arr) {
System.out.print(a + " ");
}
}
}