1.選擇排序
理解核心思想,取出一個元素,在它後面的每一位中進行比較,選擇出一個最小/最大的元素,來與它交換。
代碼示例
//比較
public static boolean less(int a, int b) {
if (a > b)
return true;
return false;
}
//交換
public static void exch(int[] num, int i, int j) {
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
//排序
public static void sort(int[] num) {
for (int i = 0; i < num.length; i++) {
int min = i;
// 除開i座標的前面的元素
for (int j = i + 1; j < num.length; j++)
// 注意理解這裏兩個比較對象。
// 後面的每一個元素與min座標比較。
// 目的是找出比min座標還小/大的值
if (less(num[j], num[min]))
min = j;
// 進行交換
exch(num, i, min);
}
}
總結
第一步,設置標記
比較出最小/最大
交換標記點下標與比較的元素。
2.插入排序
理解核心思想,取出一個元素,比較它之前的元素,進行兩兩交換。由於一開始就是這樣操作,保證了前面的數組具有有序性,從而進行交換後一樣保持有序。
代碼示例
//比較
public static boolean less(int a, int b) {
if (a > b)
return true;
return false;
}
//交換
public static void exch(int[] num, int i, int j) {
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
//排序
public static void sort(int[] num) {
for (int i = 0; i < num.length; i++) {
//比較當前i,之前的元素,進行兩兩交換操作。(關鍵)
for (int j = i; j > 0 && less(num[j], num[j - 1]); j--)
exch(num, j, j - 1);
}
}
總結
比較兩兩元素,滿足條件交換。
3.快速排序(二分法排序)
理解核心思想,選取第一位作爲標記,經過一次排序後,將這個數組分爲兩個部分(無序的),左邊的小於標記,右邊的大於標記。選取第二位,重複上面操作。最終整個數組有序。
fd
public static void sort(int[] num) {
sort(num, 0, num.length - 1);
}
public static void sort(int[] num, int left, int right) {
int pos;
if (left < right) {
//算出中間位置
pos = pos(num, left, right);
//以中間位置進行分割成兩部分
sort(num, left, pos - 1);
sort(num, pos + 1, right);
}
}
public static int pos(int[] num, int left, int right) {
int temp = num[left];
while (left < right) {
//右邊開始尋找,與標記點比較
while (left < right && num[right] >= temp)
right--;
//發現比標記點小。將右邊的小值賦值給左邊,並且將左邊的下標向前移位。因爲下面代碼要從左邊搜索了。
if (left < right)
num[left++] = num[right];
//左邊開始尋找,與標記點比較
while (left < right && num[left] <= temp)
left++;
//發現比標記點大,將左邊的大值賦值給右邊,並且將右邊的下標--,因爲代碼要從右邊搜索了。
if (left < right)
num[right--] = num[left];
}
//最終完成,最後一步是左邊的值賦值給右邊,所以此時的left就處於中間位置。我們將標記點值賦值給它,
num[left] = temp;
//返回分割點。
return left;
}
public static void main(String[] args) {
int[] num = new int[20];
Random random = new Random();
for (int i = 0; i < 20; i++) {
num[i] = random.nextInt(100);
}
sort(num);
for (int i :
num) {
System.out.print(i + "\t");
}
System.out.println();
}
總結
標記點
右邊小的賦值給左邊,左邊大的賦值給右邊
確定中間點,賦值標記點值,返回下標
4.希爾排序
理解核心思想,增量概念,每次在增量間比較,以及交換。縮小增量,重複比較,交換。利用的插入排序算法。
public void sort(int[] nums) {
/** 結合了插入排序 **/
/** 數字長度N **/
int N = nums.length;
/** 確認間隔長度 **/
int h = 3;
while (h < N / 3) h = 3 * h + 1;
while (h >= 1) {
/** 注意需要從i=h開始 i++ **/
for (int i = h; i < N; i++)
/** j=i開始 **/
for (int j = i; j >= h && less(nums[j], nums[j - h]); j -= h)//插入排序
exch(nums, j, j - h);
h = h / 3;
}
}
理解快速排序,改變其增量即可。
5.歸併排序
理解核心思想,歸併排序,類似於分支法解決問題,將一個長度很長的數組,從中間分開,分成兩半,取一半,重複上述操作即可。最終變成長度爲2的數組,比較後,進行交換,在末端保持了有序性。繼而整體保持了有序性。
/**
* @param nums
*/
public void sort(int[] nums) {
sort(nums, 0, nums.length - 1);
}
public void sort(int[] nums, int low, int high) {
int mid = low + (high - low) / 2;
if (low < high) {
/** 左邊排序 **/
sort(nums, low, mid);
/** 右邊排序 **/
sort(nums, mid + 1, high);
merge(nums, low, mid, high);
}
}
private void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;
int j = mid + 1;
int k = 0;
/** 兩邊合併**/
while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
/** 左邊多餘的合併 **/
while (i <= mid) {
temp[k++] = nums[i++];
}
/** 右邊多餘的合併 **/
while (j <= high) {
temp[k++] = nums[j++];
}
/** 拷貝合併後的數到原數組 **/
for (int k2 = 0; k2 < temp.length; k2++)
nums[low + k2] = temp[k2];
}
總結
實現末端長度爲2的數組,進行比較交換,保持了底層有序,進而整體有序。
public static void sort(int[] n) {
for (int i = 0; i < n.length; i++) {
createMaxHeap(n, n.length - 1 - i);
exch(n, 0, n.length - 1 - i);
}
}
public static void createMaxHeap(int[] n, int lastIndex) {
int pIndex = (lastIndex - 1) / 2;
for (int i = pIndex; i >= 0; i--) {
int k = i;
while (2 * k + 1 <= lastIndex) {
int cIndex = 2 * k + 1;
if (cIndex < lastIndex)
if (n[cIndex] < n[cIndex + 1])
cIndex++;
if (n[k] < n[cIndex]) {
exch(n, cIndex, k);
k = cIndex;
} else {
//關鍵的,跳過,上一級父節點
break;
}
}
}
}
總結
public static void sort(int[] n) {
int max = n[0];
int min = max;
for (int i = 0; i < n.length; i++) {
if (max < n[i])
max = n[i];
if (min > n[i])
min = n[i];
}
int[] c = new int[max - min + 1];
for (int i = 0; i < n.length; i++) {
c[n[i] - min] += 1;
}
for (int i = 0, index = 0; i < max - min + 1; i++) {
for (int j = 0; j < c[i]; j++) {
n[index++] = i + min;
}
}
}
總結