1. 选择排序
两层循环嵌套,0到n-1选出最小的,与第0个交换,缩小集合为1到n-1,选出最小的,与第一个交换……
时间复杂度:O(n2),
空间复杂度:因为中间只增加了两个新变量,存储最小值和下标,所以空间复杂度为O(1)
当数组为已排序状态时,仍需要n次比较,最好的情况仍需要O(n2)
public static void selectSort(int[] array){
for(int i = 0; i < array.length; i++){
int min = array[i];
int x = i;
for(int j = i; j < array.length; j++){
if(array[j] < min){
min = array[j];
x = j;
}
}
array[x] = array[i];
array[i] = min;
}
}
2. 冒泡排序
两两比较,将较大的值放后面,第一次循环结束后,最大值在最后,二次循环后,次大值在倒数第二个……
若某次循环,未发生任何交换,则说明队列已排序。
时间复杂度:O(n2),
空间复杂度:因为中间只增加了一个temp值做辅助,所以空间复杂度为O(1)
当数组为已排序状态时,只需要一次循环,n次比较,最好的情况只需要O(n)
public static int[] bubbleSort(int[] array) {
int temp;
boolean needNextPass = true;
for (int i = array.length - 1; i > 0 && needNextPass; i--) {
needNextPass = false;
for (int j = 0; j < i; j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
needNextPass = true;
}
}
}
return array;
}
3. 插入排序
向前面已排号的序列中插入新的值,第二层嵌套里,需要比较值,并向后移动。
时间复杂度: O(n2)
空间复杂度: O(1)
当对已排序数组处理时,第二层嵌套里不需要向后移动,最好的情况时间复杂度为O(n)
public static void insertSort(int[] array){
for(int i = 1; i < array.length; i++){
int currentValue = array[i];
int j = i - 1;
while(j >= 0 && array[j] > currentValue){
array[j + 1] = array[j];
j--;
}
array[j + 1] = currentValue;
}
}
4. 归并排序
这是一种递归的排序算法,将数组分成两组,分别排序,再合并一起。排序的总数为n,n/2,n/4,n/8……
排序在合并时,需要使用一个辅助数组。
时间复杂度:O(nlogn)
空间复杂度:O(n)
最好的情况时,即数据已排序的情况,时间复杂度为仍为O(nlogn)
public static void mergeSort(int[] array) {
if (array.length > 1){
int[] firstHalf = new int[array.length / 2];
System.arraycopy(array, 0, firstHalf, 0, array.length / 2);
mergeSort(firstHalf);
int[] sceondHalf = new int[array.length - array.length / 2];
System.arraycopy(array, array.length / 2, sceondHalf, 0, array.length - array.length / 2);
mergeSort(sceondHalf);
int temp[] = conArray(firstHalf, sceondHalf);
System.arraycopy(temp, 0, array, 0, temp.length);
}
}
public static int[] conArray(int[] array1, int[] array2) {
int m = array1.length;
int n = array2.length;
int[] temp = new int[m + n];
int i = 0,j = 0, k = 0;
while(i < m && j < n){
if(array1[i] <= array2[j]){
temp[k++] = array1[i++];
}
else{
temp[k++] = array2[j++];
}
}
while(i < m){
temp[k++] = array1[i++];
}
while(j < n){
temp[k++] = array2[j++];
}
return temp;
}
5. 快速排序
选择第一个值作为主元,将剩余值分列主元的两边,这时主元的位置是正确的位置,递归的调用这个方法,将所有的值作为主元,确定位置。
时间复杂度: O(nlogn)
空间复杂度: O(1) 不需要辅助数组
最差的情况下,主元将数组分成一个空数组和一个完整数组,时间复杂度为O(n2)
public static void quickSort(int[] array) {
quickSort(array, 0, array.length - 1);
}
public static void quickSort(int[] array, int first, int last) {
if (last - first > 0) {
int pivotIndex = partition(array, first, last);
quickSort(array, first, pivotIndex - 1);
quickSort(array, pivotIndex + 1, last);
}
}
public static int partition(int[] array, int first, int last) {
int pivot = array[first];
int low = first + 1;
int high = last;
while (high > low) {
while (low <= high && array[low] < pivot)
low++;
while (low <= high && array[high] > pivot)
high--;
if (high > low) {
int temp = array[low];
array[low] = array[high];
array[high] = temp;
}
}
while (high > first && array[high] >= pivot)
high--;
if (pivot > array[high]) {
array[first] = array[high];
array[high] = pivot;
return high;
} else
return pivot;
}