(重溫)常見的排序算法
code
package sort;
public class Main {
public static void main(String[] args) {
}
/**
* 冒泡排序
* @param arr
*/
public static void bubbleSort(int[] arr){
boolean flag = false;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr.length-1-i;j++){
if(arr[j+1]<arr[j]){
flag = true;
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
if(!flag) {
break;
}
else {
flag = true;
}
}
}
/**
* 選擇排序
* @param arr
*/
public static void selectSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
int min = arr[i];
int minIndex = i;
for(int j=i+1;j<arr.length;j++){
if(arr[j] < min){
min = arr[j];
minIndex = j;
}
}
if(minIndex != i){
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
/**
* 插入排序
* @param arr
*/
public static void InsertSort(int[] arr){
int insertVal;
int insertIndex;
for(int i=1;i<arr.length;i++){
insertVal = arr[i];
insertIndex = i-1;
while(insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex++] = arr[insertIndex];
insertIndex--;
}
if(insertIndex + 1 != i){
arr[insertIndex+1] = insertVal;
}
}
}
/**
* 快速排序
* @param arr
* @param left
* @param right
*/
public static void quickSort(int[] arr, int left, int right){
int l = left, r = right;
int mid = (l + r) / 2;
while (l < r){
while (arr[l] < arr[mid]){
l++;
}
while (arr[r] > arr[mid]){
r--;
}
if(r<=l) break;
int temp = arr[l];
arr[r] = arr[l];
arr[l] = temp;
if (arr[mid] == arr[r]){
l+=1;
}
if(arr[mid] == arr[l]){
r-=1;
}
}
if (l==r){
l+=1;
r-=1;
}
quickSort(arr,left,r);
quickSort(arr,l,right);
}
/**
* 歸併排序
* @param arr
* @param left
* @param right
* @param temp
*/
public static void mergeSort(int[] arr,int left, int right,int[] temp){
while (right > left){
int mid = (right + left) /2;
mergeSort(arr,left,mid,temp);
mergeSort(arr,mid + 1,right,temp);
merge(arr,left,mid,right,temp);
}
}
public static void merge(int[] arr,int left, int mid, int right,int[] temp){
int i = left;
int j = mid + 1;
int t = 0;
while (i <= mid&&mid <= j){
if(arr[i] < arr[j]){
temp[t++] = arr[i];
i++;
}else {
temp[t++] = arr[j];
j++;
}
}
while (j<=right){
temp[t++]=arr[j++];
}
while (i <= mid){
temp[t++] = arr[i++];
}
t=0;
int templeft = 0;
while (templeft <= right){
arr[templeft++] = temp[t++];
}
}
/**
* 基數排序
* @param arr
*/
public static void bucketSort(int[] arr){
int max = arr[0];
for(int i : arr){
if(i > max){
max = i;
}
}
int maxLength = (max + "").length();
int[][] bucket = new int[10][arr.length];
int[] bucketElementCounts = new int[10];
for(int i=0,n=1;i<maxLength;i++,n*=10){
for(int j=0;j<arr.length;j++){
int digitElement = arr[j]/n%10;
bucket[digitElement][bucketElementCounts[digitElement]] = arr[j];
bucketElementCounts[digitElement]++;
}
}
int index = 0;
for (int k=0;k<bucketElementCounts.length;k++){
if(bucketElementCounts[k]!=0){
for(int l=0;l<bucketElementCounts[k];l++){
arr[index++] = bucket[k][l];
}
}
bucketElementCounts[k] = 0;
}
}
}
常見的屬性
排序算法 | 平均時間複雜度 | 最好情況 | 最壞情況 | 空間複雜度 | 排序方式 | 穩定性 |
---|---|---|---|---|---|---|
冒泡排序 | O(n) | O(n) | O(n) | O(1) | In-place | 穩定 |
選擇排序 | O(n) | O(n) | O(n) | O(1) | In-place | 不穩定 |
插入排序 | O(n) | O(n) | O(n) | O(1) | In-place | 穩定 |
快速排序 | O(nlgn) | O(nlgn) | O(n) | O(1) | In-place | 不穩定 |
歸併排序 | O(nlgn) | O(nlgn) | O(nlgn) | O(n) | Out-place | 穩定 |
基數排序 | O(n×k) | O(n×k) | O(n×k) | O(n+k) | Out-place | 穩定 |
穩定性:穩定的算法在排序的過程中不會改變元素彼此的位置的相對次序,反之不穩定的排序算法經常會改變這個次序