【算法】分治初步
定义
分治,字面上的解释是“分而治之”,就是把一个问题分成多个的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
示例
快速排序#
把原数组分成左右两段,保证左
实现#
怎么才能让左不大于右呢?
基准值:左/右/中点/随机位置的值。 这么草率?
反正都一样。
对
i = l, j = r; 确定基准值x;
。- i向后走,当
a[i]>x
时停下,j向前走,当a[j]>x
时停下。 if(i < j) swap(a[i], a[j]);
。- 当i<j时,回到第二步。
- 对
和 分别递归,直到l >= r
。
void quick_sort(int l, int r)
{
int i = l, j = r;
int x = a[(l+r)/2]; // 基准值(此处取中点,一般建议随机数)
while(i<=j)
{
while(a[i] < x) i++;
while(a[j] > x) j--;
// i 表示小于基准值的下标,j 表示大于基准值的下标
// 找到不满足以上的 a[i], a[j]
if(i<=j) // 如果 i 在 j 左边,a[i] 和 a[j] 交换
{
swap(a[i], a[j]);
i++,j--; // 防止越界 RE
}
}
if(l<r) // 如果数列可以再分,递归
{
quick_sort(l,j);quick_sort(i,r);
}
}
第k小#
同快速排序。
但我们可以考虑一些神奇的方法。
对
qsort(l,r,k)
{
选基准值,做交换。
if(k <= j) return qsort(l,j,k);
else if(k >= i) return qsort(i, r, k);
else return x;
}
int quick_sort_mink(int l,int r,int k)
{
int i = l, j = r;
int x = a[(l+r)/2];
while(i<=j)
{
while(a[i] < x) i++;
while(a[j] > x) j--;
if(i<=j)
{
swap(a[i],a[j]);
i++,j--;
}
}
if(k <= j) return quick_sort_mink(l,j,k);
else if(k >= i) return quick_sort_mink(i,r,k);
else return x;
}
三分法#
例题:P1883 函数
归并排序#
先对左右子区间排序,然后再把两个有序子区间合并成一个完整区间。
时间复杂度:稳定的
实现#
当前区间
mid=(l+r)/2
;- 递归
; - 递归
; - 合并
;
void merge_sort(int l, int r)
{
if(l >= r) return; // 不可再分就不继续了
int mid = (l+r)/2;
merge_sort(l, mid);
merge_sort(mid+1, r);
// 递归左右区间
int i = l, j = mid+1; // 从两区间左端点开始
int cnt = l-1;
while(i <= mid && j <= r)
{
if(a[i] <= a[j]) b[++cnt] = a[i], i++;
else b[++cnt] = a[j], j++;
// 把a[i],a[j]更大的那个放进临时数组b[]
}
while(i <= mid) b[++cnt] = a[i], i++;
while(j <= r) b[++cnt] = a[j], j++;
// 把没放完的放进b[]
for(int k = l;k <= r;k++) a[k] = b[k];
// 把b[] 放回原区间
}
作者:蒟蒻Ivan
出处:https://www.cnblogs.com/ghivan911/p/17645723.html
版权:本作品采用「转载请注明出处-非商业性使用」许可协议进行许可。
本博文版权归本博主所有,未经授权不得转载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!