一、插入排序
核心想法:像排序一手扑克牌,把一张牌开始时,我们的左手为空并且桌子上的牌面向下。然后我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它已在手中的每张牌进行比较。
- 最坏情况 :O(n2) 数组反向排序
- 最好情况 :O(n) 数组已经排好序
- 平均情况 :O(n2) 确定在什么位置插入元素num,平均地数组中有一半元素大于num,一半小于num
代码:
public void insertionSort(int[] nums) {
for (int j = 1; j < length; j++) {
int key = nums[j];
int i = j - 1;
while (i >= 0 && nums[i] > key) {
nums[i + 1] = nums[i];
i--;
}
nums[i + 1] = key;
}
}
二、冒泡排序
核心想法:反复交换相邻的未按次序排列的元素。每一次选出该次最大的数字往后冒泡
- 最坏情况 :O(n2)
- 最好情况 :O(n)
- 平均情况 :O(n2)
代码:
public void bubbleSort(int[] nums) {
int len = nums.length;
for (int i = 0; i < len; i++) {
for (int j = 1; j < (len - i); j++) {
if (nums[j - 1] > nums[j]) {
int temp = nums[j - 1];
nums[j - 1] = nums[j];
nums[j] = temp;
}
}
}
}
三、归并排序
核心想法:递归, 分治法(Divide and Conquer)
分治法:分解:将数组划分为两个规模为n/2的子数组;解决:递归地对两个子数组分别排序;合并:递归地合并两个子数组。
时间复杂度分析:T(n)=2T(n/2)+O(n)->O(nlogn)
代码:
public void mergeSort(int[] nums){
mergeSort(nums, 0, nums.length-1);
}
private void mergeSort(int[] nums, int begin, int end) {
if (begin < end) {
int mid = begin + (end - begin) / 2;
mergeSort(nums, begin, mid);
mergeSort(nums, mid + 1, end);
merge(nums, begin, mid, end);
}
}
private void merge(int[] nums, int start, int mid, int end) {
int leftLen = mid - start + 1;
int rightLen = end - mid;
int[] left = new int[leftLen];
int[] right = new int[rightLen];
for (int i = 0; i < leftLen; i++) {
left[i] = nums[start + i];
}
for (int j = 0; j < rightLen; j++) {
right[i] = nums[mid + 1 + j];
}
int index = start;
int i, j = 0;
while (i < leftLen && j < rightLen) {
if (left[i] <= right[j]) {
nums[index++] = left[i++];
} else {
nums[index++] = rightLen[j++];
}
}
while (i < leftLen) {
nums[index++] = left[i++];
}
while (j < rightLen) {
nums[index++] = right[j++];
}
}
四、快速排序
核心想法:递归, 分治法(Divide and Conquer)
分治法:分解:将数组划分为两个(可能为空)子数组,使得前一个子数组中的每个元素都小于或等于nums[pivot],后一个都大于nums[pivot];解决:递归地对两个子数组分别排序;合并:由于子数组都是原地排序不需要合并
时间复杂度分析:O(nlogn)
- 例如:[6,2,8,7,4,5,1]
代码:
public void quicksort(int[] num) {
quicksort(nums, 0, num.length-1);
}
public void quicksort(int[] nums, int begin, int end) {
if (begin >= end) {
return;
}
int pivotPostion = partition(nums, begin, end);
quicksort(nums, begin, pivotPostion - 1);
quicksort(nums, pivotPostion + 1, end);
}
public int partition(int[] nums, int begin, int end) {
int pivot = nums[begin];
while (begin < end) {
while (begin < end && nums[end] >= pivot) {
end--;
}
nums[begin] = nums[end];
while (begin < end && nums[begin] <= pivot) {
begin++;
}
nums[end] = nums[begin];
}
nums[begin] = pivot;
return begin;
}