//非递归快排写法:
public static void quickSortNonRecursive(int[] array,int left,int right){
if(left>=right){
return;
}
Stack<Integer> s = new Stack<>();
s.push(left);
s.push(right);
while (!s.isEmpty()){
//这里是先出右后出左,那后边就要对应好
int r = s.pop();
int l = s.pop();
//分治
int pivotIndex = partition2(array,l,r);
// 确保左边至少有俩元素
// 左边部分
if(l < pivotIndex-1){
//后压右,先压左
s.push(l);
s.push(pivotIndex-1);
}
// 右边部分
if (r > pivotIndex+1){
//后压右,先压左
s.push(pivotIndex+1);
s.push(r);
}
}
}
"归并排序"
递归写法
🍉解析:
①主要逻辑:先分解,再合并
②
处理左子树:将左半部分不断拆分为左右子树,递归处理(先左后右)直到有序,左子树处理完毕。
处理右子树:将右半部分同样拆分为左右子树,递归处理(先左后右)直到有序,右子树处理完毕。
合并:将左右两个有序子树合并,递归结束
🌰代码实现:
java复制代码
//归并排序
public static void mergeSort(int[] array,int left,int right){
//递归出口
if(left >= right){
return;
}
//第一种写法假如left跟right过大会溢出
//int mid = (left + right)/2;
int mid = left + (right - left)/2;
//分解
mergeSort(array,left,mid);
mergeSort(array,mid+1,right);
//合并
merge(array,left,mid,right);
}
//将 [left, mid] 和 [mid+1, right] 两个有序数组合并
public static void merge(int[] array, int left, int mid, int right) {
int s1 = left; // 左半部分起始
int e1 = mid; // 左半部分结束
int s2 = mid + 1; // 右半部分起始
int e2 = right; // 右半部分结束
//创建临时数组
int[] tmpArray = new int[right - left + 1];
//k是临时数组的下标
int k = 0;
while (s1 <= e1 && s2 <= e2) {
if (array[s1] <= array[s2]) {
tmpArray[k++] = array[s1++];
} else {
tmpArray[k++] = array[s2++];
}
}
//走到这里说明:
// 左半部分(s1..e1)或右半部分(s2..e2)中,至少有一边已经全部被取到 tmpArray 里了
while (s1 <= e1) {
tmpArray[k++] = array[s1++];
}
while (s2 <= e2) {
tmpArray[k++] = array[s2++];
}
//将临时数组拷贝回原数组
//注意这里的left+i
for (int i = 0; i < tmpArray.length; i++) {
array[left + i] = tmpArray[i];
}
}
非递归写法
🍉解析:
①gap为1时,合并成两个两个的,gap为2时合并成四个四个的...
②当gap执行完毕时,gap变成了8,循环结束
🌰代码实现:
java复制代码
public static void mergeSortNor(int[] array) {
int gap = 1; // 初始子数组长度为1
while (gap < array.length) { // 当长度小于数组总长度时继续合并
for (int i = 0; i < array.length; i = i + 2*gap) {
// 确定三个关键位置
int left = i;
int mid = left + gap - 1;
if(mid >= array.length) {
mid = array.length-1;
}
int right = mid + gap;
if(right >= array.length) {
right = array.length-1;
}
merge(array, left, mid, right);
}
gap *= 2; // 子数组长度翻倍
}
}