常見的內部排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸並排序、快速排序、堆排序、基數排序等。用一張圖概括:

冒泡排序
算法步驟
比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。這步做完后,最后的元素會是最大的數。
針對所有的元素重復以上的步驟,除了最后一個。
持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
Java 代碼實現
import java.util.Arrays;
public class MaoPao {
public static void main(String[] args){
int[] arr = {1,45,43,12,91,4,66,82,19,213};
arr = sort(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] sort(int[] sourceArray) {
// 對 arr 進行拷貝,不改變參數內容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
for (int i = 1; i < arr.length; i++) {
// 設定一個標記,若為true,則表示此次循環沒有進行交換,也就是待排序列已經有序,排序已經完成。
boolean flag = true;
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = false;
}
}
if (flag) {
break;
}
}
return arr;
}
}
選擇排序
算法步驟
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。
重復第二步,直到所有元素均排序完畢。
Java 代碼實現
import java.util.Arrays;
public class XuanZe {
public static void main(String[] args) {
int[] arr = {1,45,43,12,91,4,66,82,19,213};
arr = sort(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] sort(int[] sourceArray){
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
// 總共要經過 N-1 輪比較
for (int i = 0; i < arr.length - 1; i++) {
int min = i;
// 每輪需要比較的次數 N-i
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
// 記錄目前能找到的最小值元素的下標
min = j;
}
}
// 將找到的最小值和i位置所在的值進行交換
if (i != min) {
int tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}
}
return arr;
}
}
插入排序
算法步驟
將第一待排序序列第一個元素看做一個有序序列,把第二個元素到最后一個元素當成是未排序序列。
從頭到尾依次掃描未排序序列,將掃描到的每個元素插入有序序列的適當位置。(如果待插入的元素與有序序列中的某個元素相等,則將待插入元素插入到相等元素的后面。)
Java 代碼實現
import java.util.Arrays;
public class ChaRu {
public static void main(String[] args) {
int[] arr = {1,45,43,12,91,4,66,82,19,213};
arr = sort(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] sort(int[] sourceArray){
// 對 arr 進行拷貝,不改變參數內容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
// 從下標為1的元素開始選擇合適的位置插入,因為下標為0的只有一個元素,默認是有序的
for (int i = 1; i < arr.length; i++) {
// 記錄要插入的數據
int tmp = arr[i];
// 從已經排序的序列最右邊的開始比較,找到比其小的數
int j = i;
while (j > 0 && tmp < arr[j - 1]) {
arr[j] = arr[j - 1];
j--;
}
// 存在比其小的數,插入
if (j != i) {
arr[j] = tmp;
}
}
return arr;
}
}
快速排序
算法步驟
-
從數列中挑出一個元素,稱為 "基准"(pivot);
-
重新排序數列,所有元素比基准值小的擺放在基准前面,所有元素比基准值大的擺在基准的后面(相同的數可以到任一邊)。在這個分區退出之后,該基准就處於數列的中間位置。這個稱為分區(partition)操作;
-
遞歸地(recursive)把小於基准值元素的子數列和大於基准值元素的子數列排序;
Java 代碼實現
import java.util.Arrays;
public class KuaiSu {
public static void main(String[] args) {
int[] arr = {1,45,43,12,91,4,66,82,19,213};
arr = sort(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] sort(int[] sourceArray){
// 對 arr 進行拷貝,不改變參數內容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
return quickSort(arr, 0, arr.length - 1);
}
private static int[] quickSort(int[] arr, int left, int right) {
if (left < right) {
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
private static int partition(int[] arr, int left, int right) {
// 設定基准值(pivot)
int pivot = left;
int index = pivot + 1;
for (int i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index - 1;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}

