排序是計算機科學中一個重要的問題,因為它經常用於數據庫查詢、數據壓縮等應用中。排序算法是將一組數據按照特定規則排列的過程,可以將數組或列表按升序或降序排列。
一、冒泡排序
冒泡排序是最簡單但同時也是最低效的算法之一。此算法在每輪比較中,會比較相鄰兩個元素,如果順序錯誤,就交換它們。因為每輪比較都會讓一個最大或最小值「浮」到數組的頂端(首位),所以稱為冒泡排序。
public void bubbleSort(int[] arr) { int temp; //外層循環控制排序次數 for(int i = 0; i < arr.length - 1; i++) { //內層循環控制從頭到i已有序無需再排序的元素 for(int j = 0; j arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
二、快速排序
快速排序是一種基於比較的排序算法,通過選取一個基準值(pivot)並通過一趟排序將要排序的數據分割成獨立的兩部分,左邊的小於基準值,右邊的大於基準值。然後再按照此方法對這兩部分分別進行快速排序,直到整個序列有序。
public void quickSort(int[] arr, int left, int right) { if(left < right) { int pivot = partition(arr, left, right); quickSort(arr, left, pivot - 1); quickSort(arr, pivot + 1, right); } } private int partition(int[] arr, int left, int right) { int pivot = arr[left]; while (left < right) { while ((left = pivot)) { right--; } arr[left] = arr[right]; while ((left < right) && (arr[left] <= pivot)) { left++; } arr[right] = arr[left]; } arr[left] = pivot; return left; }
三、歸併排序
歸併排序是基於分治思想的排序算法,將待排序數組分成左右兩部分,分別對左右部分進行歸併排序,最後將兩個有序部分歸併成一個有序數組。歸併排序的時間複雜度為O(NlogN),是十分高效的排序算法。
public void mergeSort(int[] arr, int left, int right) { if (left < right) { int mid = (left + right) / 2; mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); merge(arr, left, mid, right); } } private void merge(int[] arr, int left, int mid, int right) { int[] temp = new int[right - left + 1]; int i = left, j = mid + 1, k = 0; while (i <= mid && j <= right) { if (arr[i] < arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } System.arraycopy(temp, 0, arr, left, temp.length); }
四、堆排序
堆排序是基於完全二叉樹的排序算法,通過構建最大堆或最小堆,將根節點與末節點交換並重新構建堆,可以得到一個有序序列。堆排序的時間複雜度為O(NlogN),是一種高效的排序算法。
public void heapSort(int[] arr) { for (int i = arr.length / 2 - 1; i >= 0; i--) { adjustHeap(arr, i, arr.length); } for (int i = arr.length - 1; i >= 0; i--) { swap(arr, 0, i); adjustHeap(arr, 0, i); } } private void adjustHeap(int[] arr, int i, int length) { int temp = arr[i]; for (int k = i * 2 + 1; k < length; k = k * 2 + 1) { if (k + 1 < length && arr[k] temp) { arr[i] = arr[k]; i = k; } else { break; } } arr[i] = temp; } private void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }
五、選擇排序
選擇排序是一種簡單直觀的排序算法,每次從未排序的數據中選擇最小(或最大)的元素,放到已排序數據末尾(或開頭),以此類推,直到所有數據都排序完畢。此算法的時間複雜度始終為O(N^2),不適合大規模數據的排序。
public void selectionSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { int minIndex = i; for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } if (minIndex != i) { int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } }
六、插入排序
插入排序是一種簡單直觀的排序算法,將數組分為已排序和未排序兩部分,每次將未排序部分的第一個元素插入到己排序部分的正確位置。此算法的時間複雜度始終為O(N^2),不適合大規模數據的排序。
public void insertionSort(int[] arr) { for (int i = 1; i = 0 && arr[j] > temp) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = temp; } }
七、總結
七種排序算法分別是冒泡排序、快速排序、歸併排序、堆排序、選擇排序和插入排序。這些算法各有所長,應根據具體情況進行選擇。在實際開發中,建議使用Java集合框架提供的排序方法,如:Collections.sort()方法。
原創文章,作者:TDUG,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/148032.html