📟作者主页:慢热的陕西人
🌴专栏链接:C++算法
📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言
主要讲解C++算法中所涉及到的两个排序算法,快排和归并。
文章目录
- Ⅰ.排序
- Ⅰ. Ⅰ 快排
- Ⅰ. Ⅱ 归并
Ⅰ.排序
Ⅰ. Ⅰ 快排
思路:
平均时间复杂度:
nlogn
; ①确定分界点:即选择一个标准值
key
,key
的选取方法有q[l]
,q[(l + r) / 2]
,q[r]
,随机; ②调整位置:将数组分为两个区间,前半部分区间都是
q[i] <= key
, 后半部分区间都是q[i] >= key
③递归处理左右两端的区间;
模板:
#include<iostream> using namespace std; const int N = 1e6 + 10; int n; int q[N]; 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[i] > x); if(i < j) swap(q[i], q[j]); } quick_sort(q,l,j); quick_sort(q,j + 1, r); } int main() { scanf("%d", &n); for(int i = 0; i < n; ++i) scanf("%d", &q[i]); quick_sort(q,l,r); for(int i = 0; i < nl ++i) printf("%d ",q[i]); return 0; }
注意:
对于边界问题:
当我们选择key为q[l]的时候,那么递归的时候边界就只能是:
quick_sort(q,l,j); quick_sort(q,j + 1, r);
如果边界是如下所示的情况,就容易造成死递归,举例数组为
1 2
的情况:这时候
key
就是1,那么如下条件就会变成左区间[0, -1]
, 右区间[0, 1]
就会死递归了。所以为了避免这种情况,当选取
key
为q[l]
的时候选用上面的区间即可,当选取key
为q[r]
的时候我们选用下面的区间即可。quick_sort(q,l,i - 1); quick_sort(q,i, r);
Ⅰ. Ⅱ 归并
思路:
时间复杂度:
nlogn
; ①确定分界点
mid = (l + r) / 2
; ②不断的将数组进行分解,直到分解为一个一个为一组为止。
③将这些分解完的**有序**数组一个一个进行有序合并。
模板:
#include<iostream> using namespace std; const int N = 1000010; int n; int q[N], 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 k = 0, i = l, j = mid + 1; while (i <= mid && j <= r) if (q[i] <= q[j]) tmp[k++] = q[i++]; else tmp[k++] = q[j++]; while (j <= r) tmp[k++] = q[j++]; while (i <= mid) tmp[k++] = q[i++]; for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j]; } int main() { int n; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &q[i]); merge_sort(q, 0, n); for(int i = 0; i < n; i++) printf("%d ", q[i]); return 0; }
到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正