首先,我们来看一下各排序算法的时间复杂度:
排序算法 | 时间复杂度(平均) | 时间复杂度(最好) | 时间复杂度(最差) | 空间复杂度 | 稳定性 |
冒泡排序 | O(n) | | O(1) | 稳定 | |
选择排序 | | | | O(1) | 不稳定 |
希尔排序 | O(n) | | O(1) | 不稳定 | |
插入排序 | O(n) | O(1) | 稳定 | ||
快速排序 | 不稳定 | ||||
归并排序 | O(n) | 稳定 |
冒泡排序
/**
冒泡排序,从小到大
进阶版可添加标志,判断是否已然有序
*/
public static void bubbleSort(int[] nums) {
// 能到达的右边界
for (int i = nums.length - 1; i >= 0; i--) {
// 冒泡
for (int j = 1; j <= i; j++) {
if (nums[j - 1] > nums[j]) {
int temp = nums[j];
nums[j] = nums[j - 1];
nums[j - 1] = temp;
}
}
}
}
选择排序
/**
选择排序,从小到大
*/
public static void selectSort(int[] nums) {
int min = 0,temp=0;
for(int i=0;i<nums.length;i++) {
min = i;
for(int j=i+1;j<nums.length;j++) {
if(nums[j]<=nums[min]) {
min = j;
}
}
if(min!=i) {
temp = nums[i];
nums[i] = nums[min];
nums[min] = temp;
}
}
}
插入排序
/**
* 插入排序:从小到大
* @param nums
*/
public static void insertSort(int[] nums) {
for(int i=1;i<nums.length;i++) {//比较的趟数
for(int j=i-1;j>=0;j--) {
if(nums[j+1]<nums[j]) {
int temp = nums[j+1];
nums[j+1] = nums[j];
nums[j] = temp;
}
}
}
}
希尔排序
/**
* 希尔排序:从小到大
* @param nums
*/
public static void shellSort(int[] nums) {
for(int dk = nums.length/2;dk>0;dk/=2) {//增量、步数
for(int i=dk;i<nums.length;i++) {//遍历
int value = nums[i];
for(int j = i-dk;j>=0 && nums[j]>value;j=j-dk) {//同组比较
nums[j+dk] = nums[j];
nums[j] = value;
}
}
}
}
快速排序
/**
* 快速排序:从小到大
* @param nums
*/
public static void quickSort(int[] nums, int low, int high) {
if(low<high) {
int pivotIndex = partition(low, high, nums);
//对左侧进行快排
quickSort(nums, low, pivotIndex-1);
//对右侧进行快排
quickSort(nums, pivotIndex+1, high);
}
}
private static int partition(int low, int high,int nums[]) {
int i=low, j=high, pivot=nums[low];
while(i<j) {
while(j>i && nums[j]>=pivot) {
j--;
}
nums[i] = nums[j];
while(i<j && nums[i]<=pivot) {
i++;
}
nums[j] = nums[i];
}
nums[i] = pivot;
return i;
}
归并排序
/**
* 归并排序
* @param nums
*/
public static void mergeSort(int[] nums, int left, int right) {
int mid = (right + left)/2; //注意注意注意注意注意注意,这里是(right + left)/2,而不是(right - left)/2
if(left<right) {
//左侧
mergeSort(nums, left, mid);
//右侧
mergeSort(nums, mid+1, right);
merge(nums, left, mid, right);
}
}
/**
* [low,...,mid] [mid+1,...,high]
* @param nums
* @param low
* @param mid
* @param high
*/
private static void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high-low+1];
int index = 0;
new TreeSet<Integer>();
int i=low,j=mid+1;
while(i<=mid && j<=high) {
if(nums[i]<nums[j]) {
temp[index++] = nums[i++];
}else {
temp[index++] = nums[j++];
}
}
while(i<=mid) {
temp[index++] = nums[i++];
}
while(j<=high) {
temp[index++] = nums[j++];
}
for(int e:temp) {
nums[low++] = e;
}
}