Complexity
Sort | Time avg | Time best | Time worst | Space | Stable |
---|---|---|---|---|---|
insertion | n^2(折半插入可以减少比较次数,但是移动次数不变) | n(排好序时,对于每个a[i]只比较一次) | n^2 | 1 | Yes |
selection | n^2 | n^2 | n^2 | 1 | No |
bubble | n^2 | n(一趟没交换就可以结束) | n^2 | 1 | Yes |
merge | nlogn | nlogn | nlogn | n(临时数组) | Yes |
quick | nlogn(unifromly partition, tree hight is logn) | nlogn | n^2(逆序,递归树不分叉,高n。每次扫描只比上次扫描少一个元素,故(1+…+n)~=n^2)(avoid by shuffle)( 当划分产生的两个子问题分别包含 n-1 和 0 个元素时,最坏情况发生, n/2, n/2时最好情况发生) | best = logn, worst = n(递归次数,stack所占空间) | No |
Code
Insertion Sort
a[0:i-1] done, insert a[i] to a[0:i-1] (using swap).
private static void insertionSort(int[] array) {
for(int i = 1; i < array.length; i++) {
for(int j = i; j > 0; j--) {
if(array[j] < array[j-1]) {
int temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
}
}
}
}
Selection Sort
a[0:i-1] done, select min a[j] from a[i:n-1], swap with a[i].
private static void selectionSort(int[] array) {
for(int i = 0; i < array.length; i++) {
int smallestIndex = i;
for(int j = i + 1; j < array.length; j++) {
if(array[j] < array[smallestIndex]) {
smallestIndex = j;
}
}
int temp = array[i];
array[i] = array[smallestIndex];
array[smallestIndex] = temp;
}
}
Bubble Sort
a[i:n-1] done, swap adjacent elements in a[0:i-1] if a[j] > a[j+1].
private static void bubbleSort(int[] array) {
for(int i = array.length - 1; i > 0; i--) {
for(int j = 0; j < i; j++) {
if(array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
Merge Sort
private static void mergeSort(int[] array, int left, int right) {
if(left >= right) {
return;
}
int mid = left + (right - left) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, mid, right);
}
private static void merge(int[] array, int left, int mid, int right) {
int lenLeft = mid - left + 1;
int lenRight = right - mid;
int[] tempLeft = new int[lenLeft];
int[] tempRight = new int[lenRight];
for(int i = 0; i < lenLeft; i++) {
tempLeft[i] = array[i + left];
}
for(int i = 0; i < lenRight; i++) {
tempRight[i] = array[mid + i + 1];
}
int i = 0;
int j = 0;
int index = left;
while(i < lenLeft && j < lenRight) {
if(tempLeft[i] < tempRight[j]) {
array[index++] = tempLeft[i++];
} else {
array[index++] = tempRight[j++];
}
}
while(i < lenLeft) {
array[index++] = tempLeft[i++];
}
// 其实不需要这一part,因为array里后半部分顺序本来就和tempRight的一样
// while(j < lenRight) {
// array[index++] = tempRight[j++];
// }
}
Quick Sort
choose one element as pivot, move a[i] <= pivot to left, a[i] >= pivot to right, then recursively solve two part.
private static void quickSort(int[] array, int left, int right) {
if(left >= right) {
return;
}
int i = left;
int j = right;
int pivot = array[left + (right - left) / 2];
while(i <= j) {
while(i <= j && array[i] < pivot) {
i++;
}
while(i <= j && array[j] > pivot) {
j--;
}
if(i <= j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
quickSort(array, left, j);
quickSort(array, i, right);
}