1.交换排序
(1)快速排序:采用分治的思想,选出基准值来排序[递归版本]
1.2.1:基准值为第一个元素[固定位置基准值法]
对应图解:
对应代码:
//求每次的基准值
public static int partion(int[] array,int left,int right){
int temp = array[left];
while (left<right){
while (left<right&&array[right]>=temp){
right--;
}
if(left>=right){
break;
}else{
array[left] = array[right];
}
while (left<right&&array[left]<=temp){
left++;
}
if(left>=right){
break;
}else{
array[right] = array[left];
}
}
array[left] = temp;//或者array[right] = temp;
return left;
}
//快排
public static void quickSort(int[] array,int start,int end){
int par = partion(array,start,end);
if(par>start+1){
quickSort(array,start,par-1);
}
if(par<end-1){
quickSort(array,par+1,end);
}
}
1.2.2:三数取中基准值法
对应图解:
对应代码:
//求基准值
public static int partion(int[] array,int low,int high){
int temp = array[low];
while (low<high){
while (low<high && array[high]>=temp){
high--;
}
if(low>=high){
break;
}else{
array[low] = array[high];
}
while (low<high && array[low]<=temp){
low++;
}
if(low>=high){
break;
}else{
array[high] = array[low];
}
}
array[low] = temp;
return low;
}
public static void swap(int[] array,int low,int high ){
int temp = array[low];
array[low] = array[high];
array[high] = temp;
}
//三数取中
public static void medianOfThree(int[] array,int start,int end){
//mid<low<high
int mid = (start+end)/2;
if (array[mid]>array[start]){
swap(array,mid,start);
}
if (array[mid]>array[end]){
swap(array,mid,end);
}
if (array[start]>array[end]){
swap(array,start,end);
}
}
//快排
public static void quick(int[] array,int start,int end){
medianOfThree(array,start,end);
int par = partion(array,start,end);
//递归左边
if(par>start+1) {
quick(array, start, par - 1);
}
//递归右边
if(par<end-1){
quick(array,par+1,end);
}
}
(2)快速排序:[非递归版本]
对应代码:
//找基准值
public static int partion(int[] array,int left,int right){
int temp = array[left];
while (left<right){
while (left<right&&array[right]>=temp){
right--;
}
if(left>=right){
break;
}else{
array[left] = array[right];
}
while (left<right&&array[left]<=temp){
left++;
}
if(left>=right){
break;
}else{
array[right] = array[left];
}
}
array[left] = temp;//或者array[right] = temp;
return left;
}
//快排
public static void quickSort1(int[] array){
int start = 0;
int end = array.length-1;
int par = partion(array,start,end);
Stack<Integer> stack = new Stack<Integer>();
if (par>start+1){
stack.push(start);
stack.push(par-1);
}
if (par<end-1){
stack.push(par+1);
stack.push(end);
}
while (!stack.empty()){
end = stack.pop();
start = stack.pop();
par = partion(array,start,end);
if(par>start+1){
stack.push(start);
stack.push(par-1);
}
if(par<end-1){
stack.push(par+1);
stack.push(end);
}
}
}
注:时间复杂度:O(NlogN) 空间复杂度:logN 稳定性:不稳定
2. 归并排序:
(1)归并排序:
对应图解:
1.1[递归算法]
对应代码:
//合并函数
public static void meger(int[] array,int start,int end,int mid){
int[] temp = new int[array.length];
int tmpIndex = start;
int s1 = start;
int s2 = mid+1;
while (start<=mid && s2<=end){
if (array[start]<array[s2]){
temp[tmpIndex] = array[start];
tmpIndex++;
start++;
}else{
temp[tmpIndex++] = array[s2++];
}
}
while (start<=mid){
temp[tmpIndex++] = array[start++];
}
while (s2<=end){
temp[tmpIndex++] = array[s2++];
}
while (s1<=end){
array[s1] = temp[s1++];
}
}
//分治算法
public static void mergeSort(int[] array,int start,int end){
if(start>=end){
return;
}//分为单个数据结束,否则一直分
int mid = (start+end)/2;
mergeSort(array,start,mid);
mergeSort(array,mid+1,end);
meger(array,start,end,mid);//合并函数
}
1.2:非递归算法:
对应代码:
//合并
public static void merge1(int[] array,int gap){
int[] temp = new int[array.length];
int i = 0;
int start1 = 0;
int end1 = start1+gap-1;
int start2 = end1+1;
int end2 = start2+gap-1<array.length-1?start2+gap-1:array.length-1;
while (start2<array.length){
//比较
while (start1<=end1&&start2<=end2){
if (array[start1]>=array[start2]){
temp[i++] = array[start2++];
}else{
temp[i++] = array[start1++];
}
}
while (start1<=end1){
temp[i++] = array[start1++];
}
while (start2<=end2){
temp[i++] = array[start2++];
}
//一次二路归并结束
start1 = end2+1;
end1 = start1+gap-1;
start2 = end1+1;
end2 = start2+gap-1 <= array.length-1 ? start2+gap-1:array.length-1;
}
while (start1<array.length){
temp[i++] = array[start1++];
}
//拷贝数据到原始数组
for (int j =0;j<temp.length;j++){
array[j] = temp[j];
}
}
//拆分
public static void mergeSort1(int[] array){
for (int i = 1;i<array.length;i*=2){//组的个数
merge1(array,i);
}
}
注:时间复杂度:O(NlogN) 空间复杂度:O(n) 稳定性:稳定