6.快速排序
下面写一个伪代码
Hoare版
// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int[] array, int left, int right){
if(right - left <= 0)
return;
// 按照基准值对array数组的 [left, right)区间中的元素进行划分
int div = partition(array, left, right);
// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
// 递归排[left, div)
QuickSort(array, left, div);
// 递归排[div+1, right)
QuickSort(array, div+1, right);
}
private static int partition(int[] array, int left, int right) {
int i = left;
int j = right;
int pivot = array[left];
while (i < j) {
while (i < j && array[j] >= pivot) {
j--;
}
while (i < j && array[i] <= pivot) {
i++;
}
swap(array, i, j);
}
swap(array, i, left);
return i;
}
挖坑版
// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int[] array, int left, int right)
{
if(right - left <= 0)
return;
// 按照基准值对array数组的 [left, right)区间中的元素进行划分
int div = partition(array, left, right);
// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
// 递归排[left, div)
QuickSort(array, left, div);
// 递归排[div+1, right)
QuickSort(array, div+1, right);
}
private static int partition(inr[] array,int left,int right){
int i = left;
int j = right;
int pivot = array[left];
while(i<j){
while(i<j && array[j] >=pivot){
j--;
}
array[i] = array[j];
while(i<j&&array[i]<=pivot){
i++;
}
array[j] = array[i];
}
array[i]=pivot;
return i;
}
时间 复杂度:O(N*logN)
空间复杂度:O(logN)
稳定性:不稳定
最核心的是partition
7.归并排序
归并排序(
MERGE-SORT
)是建立在归并操作上的一种有效的排序算法
,
该算法是采用分治法(
Divide and Conquer
)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使
子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:
public static void mergeSortNor(int[] array){
int gap =1;
while(gap<array.length){
for(int i = 0;i<array.length;i+=2*gap){
int left = i;
int mid = left+gap-1;
int right = mid+gap;
//修正mid
if(mid>=array.length){
mid = array.length - 1;
}
int right = mid+gap;
//修正right
if(right>=array.length){
right = array.length -1;
}
merge(array,left,mid,right);
}
gap*=2;
}
//********合并********
private static void merge(int[] array,int low,int mid,int high){
int s1 = low;
int e1 = mid;
int s2 = mid+1;
int e2 = high;
int[] tmpArr = new int[high-low+1];
int k = 0;
//证明两个段都有数据
while(s1<=e1 && s2<=e2){
if(array[s1] <= array[s2]){
tmpArr[k++] = array[s1++];
}else{
tmpArr[k++] = array[s2++];
}
}//剩余元素,全部挪过来
while(s1<=e1){
tmpArr[k++]=array[s1++];
}
//剩余元素全部挪过来
while(s2<=e2){
tmpArr[k++] = array[s2++];
}
for(int i = 0;i<tmpArr.length;i++){
array[i+low] = tmpArr[i];
}
}
时间复杂度:log₂n
空间复杂度:n
稳定性:稳定(稳定的有 插入,冒泡,归并)
最核心的地方是merge
下面是递归的归并排序