此两种排序的注意事项:
- 都需要一个函数来使用two pointers从数组的两侧开始向内遍历
- 都需要一个函数来表现排序顺序,比如先左后右,merge/partition到底要放在何处,需要写者的算法逻辑清晰
- merge是先排序,后归并
- quicksort是先分治,再排序
- quicksort不同于二分,二分需要遍历到left=right进行查找,而quicksort在left==right时及时跳出,将一开始存储的left处的数据进行回存,从而保证左侧数据均小于且右侧数据均大于现arr[left]
归并排序
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
void merge(int A[],int L1,int L2,int R1,int R2){
int i=L1,j=L2;
int temp[100005];
int index=0;
while(i<=R1&&j<=R2){
if(A[i]<=A[j]) temp[index++]=A[i++];
else temp[index++]=A[j++];
}
while(i<=R1) temp[index++]=A[i++];
while(j<=R2) temp[index++]=A[j++];
for(int x=0;x<index;x++)
A[L1+x]=temp[x];
}
void mergesort(int A[],int left,int right){
if(left<right){
int mid=(left+right)/2;
mergesort(A,left,mid);
mergesort(A,mid+1,right);
merge(A,left,mid+1,mid,right);
}
}
int main(){
int m=0;
scanf("%d",&m);
while(m--){
int arr[100005]={
0};
int n=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
mergesort(arr,0,n-1);
for(int i=0;i<n;i++){
printf("%d\n",arr[i]);
}
}
return 0;
}
快速排序
#include <stdio.h>
int partition(int arr[],int left,int right){
int temp=arr[left];
while(left<right){
while(arr[right]>temp&&left<right) right--;
arr[left]=arr[right];//注意要在这里就解决,在最后right会改变
while(arr[left]<=temp&&left<right) left++;
arr[right]=arr[left];
}
arr[left]=temp;
//在此处左侧的都比temp小,右侧的都比temp大
return left;//需要返回下标作为下一次quicksort的位置,类似mid
}
void quicksort(int arr[],int left,int right){
if(left<right){
int pos=partition(arr,left,right);
quicksort(arr,left,pos-1);
quicksort(arr,pos+1,right);
}
}
int main(){
int arr[5005]={
0};
int n=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
quicksort(arr,0,n-1);
for(int i=0;i<n;i++){
printf("%d\n",arr[i]);
}
return 0;
}