1.快排
算法思想
通过分治1策略,将序列分组排序。
实现步骤
- 确定分界点:可以是左边界、右边界、中间点、随机点并将之记录。
- 调整区间:将小于等于记录点的数据调整至记录点左边,大于等于记录点的数据调整至记录点右边。
- 递归处理左右两段。
代码实现
void quick_sort(int q[],int l,int r){
if(l>=r) return;//如果数组只有一个或没有元素就退出。
//调整区间
int x=q[l],i=l-1,j=r+1;
while (i<j){
do i++;while (q[i]<x);
do j--;while (q[j]>x);
if(i<j) swap(q[i],q[j]);
}
//递归调用
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
几点注意
- swap没有定义可以简单替换
int a=q[i];
q[i]=q[j];
q[j]=a;
-
注意边界问题
当递归调用中使用左指针作为边界时,分界点不能选取左边界
当递归调用中使用右指针作为边界时,分界点不能选取右边界
-
注意指针问题
由于先执行了指针移动,所以在递归中需注意指针位置
2. 归并
算法思想
同快排,都用到了分治的思想,与快排不同的是归并与快排的递归调用位置有所差异。
实现步骤
- 确定分界点:mid=(l+r)/2。
- 递归排序:将序列不断分为left和right两部分。
- 归并:将left和right两部分合二为一。属于难点
代码实现
void merge_sort(int q[],int l,int r){
if (l>=r)return;//如果没有元素或只有一个元素就返回
//确定分界点
int mid=(l+r)>>1;
//递归
merge_sort(q,l,mid),merge_sort(q,mid+1,r);
//归并
int k=0,i=l,j=mid+1;
while (i<=mid&&j<=r)
if(q[i]<=q[j]) temp[k++]=q[i++];
else temp[k++]=q[j++];
while (i<=mid) temp[k++]=q[i++];
while (j<=r) temp[k++]=q[j++];
//将临时数组中数据放回原数组
for (i=l,j=0;j<=r;i++,j++) q[i]=temp[j];
}
其思想是把问题分成两个大致相等的子问题,然后递归地对他们求解,这是“分”部分。“治”阶段将两个子问题的解合并在一起并可能在做少量的附加工作,最后得到整个问题的解。 ↩︎