📂算法
🔖算法
2023-01-01 21:12阅读: 21评论: 0推荐: 0

01排序

快速排序

问题

将序列 q 的 l ~ r 区间排序
void quick_sort(int q[], int l, int r)

基本思想 —— 分治

  1. 找一个参考值 x
  2. 通过双指针算法交换使得 左半边全部是 <= x , 右半边全部是 >= x
    1. 移动左指针 i ,找到大于 x 的数
    2. 移动右指针 j ,找到小于 x 的数
    3. 交换逆序对
  3. 递归处理 左半边 右半边

模板

void quick_sort(int q[], int l, int r){
if(l >= r) return;
int i = l - 1, j = r + 1, x = q[l] + q[r] >> 1;
while(i < j){
while(q[++ i] < x);
while(q[-- j] > x);
if(i < j) swap(q[i],q[j]);
}
quick_sort( q, l, j), quick_sort( q, j + 1, r);
}

注意点: 分界点的选择可以是[ l , j ]、 [ j + 1 , r ] 或者 [ l, i - 1 ]、[ i , r ],
swap 的时候不要忘记判断 i < j

归并排序

与快排的先排完上层,再排下层不同,归并排序是先排完下层再排上层

问题

将序列 q 的 l ~ r 区间排序
void merge_sort(int q[], int l, int r)

基本思想

  1. 先排完左半边[ l , mid ]、再排完右半边[ mid + 1, r ]
  2. 将左右两个有序序列进行合并
    1. i , j 两个指针分别指向两个有序子序列的头,哪个小就输出哪个,并指向后一个,直到有一个序列指针到达末尾
    2. 将未全部输出的序列全部输出
  3. 处理左半边 和 右半边 同样使用递归的方式

模板

int tmp[N]; // 很大,最好开在外面
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 i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r){
if(q[i] <= q[j]) tmp[k ++] = q[i ++];
else tmp[k ++] = q[j ++];
}
while(i <= mid) tmp[k ++] = q[i ++];
while(j <= r) tmp[k ++] = q[j ++];
for(int i = l, j = 0; i <= r; i ++, j ++) q[i] = tmp[j];
}

本文作者:咿呀咿呀悠

本文链接:https://www.cnblogs.com/da-zhi/p/17018604.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   咿呀咿呀悠  阅读(21)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 辞 九门回忆 REOL
辞 九门回忆 - REOL
00:00 / 00:00
An audio error has occurred.

作词 : 虫二颠

作曲 : 唯子/妖狐公子

一曲定重楼

一眼半生筹

看的全都是那诡谲云涌

入得此门不回首

无需宣之于口

我对案再拜那风雨瓢泼的残陋

再聚首

戏子多秋

可怜一处情深旧

满座衣冠皆老朽

黄泉故事无止休

戏无骨难左右

换过一折又重头

只道最是人间不能留

误闯天家

劝余放下手中砂

张口欲唱声却哑

粉面披衣叫个假

怜余来安座下

不敢沾染佛前茶

只作凡人赴雪月风花

绕过胭脂楼

打散结发扣

唱的全都是那情深不寿

入得此门不回首

无需宣之于口

我对镜遮掩那风雨瓢泼的残陋

碑已旧

戏子多秋

可怜一处情深旧

满座衣冠皆老朽

黄泉故事无止休

戏无骨难左右

换过一折又重头

只道最是人间不能留

误闯天家

劝余放下手中砂

送那人御街打马

才子佳人断佳话

怜余来苦咽下

求不得佛前茶

只留三寸土种二月花