初学快排
忘记了快排的算法,所以在前段时间的蓝桥杯中对于快排找出第N个小的数时候没写出来,今天过来恶补一下
快排,全称:快速排序算法(quick sort)
其用到了分治的思想,算法实现过程百度百科就写的很不错
下面内容部分引用来着百度百科:https://baike.baidu.com/item/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/369842?fr=aladdin#2_2
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
- 一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直 至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
注意:不要把三步和第四步的执行顺序搞反,先从后面开始,然后才是从前面开始,对于交换位置时,不要直接两个值进行交换。
- 直接掉用函数
#include<cstdio> #include<cstdlib> #include<iostream> using namespace std; int cmp(const void *a,const void *b) { return (*(int*)a - *(int*)b); } int main() { int a[] = { 0, 4, 1, 3, 2, 5, 8, 7, 9, 6 }; qsort(a, 10, sizeof(int), cmp); for (int i = 0; i < 10; i++) cout << a[i] << " "; cout << endl; return 0; }
- 手写快排
#include<cstdio> #include<iostream> using namespace std; void qsort(int a[], int low, int high) { if (low >= high)return; int s = low, e = high; int key = a[s]; while (s < e){ while (s < e && a[e] >= key) e--; a[s] = a[e]; while (s < e && a[s] <= key) s++; a[e] = a[s]; } a[s] = key; //交换也是一门艺术的存在 qsort(a, low, s - 1); qsort(a, s + 1, high); } int main() { int a[] = { 1, 5, 2, 3, 4, 9, 7, 8, 6 }; qsort(a, 0, 8); for (int i = 0; i < 8; i++) cout << a[i] << " "; cout << endl; return 0; }
2018年蓝桥杯第五题填空,从n个元素中找出第k个小的数,每进行一趟快排,如果当前i的位置大于k,则递归在左侧继续寻找;如果当前i的位置小于k,则在
递归在其右侧继续寻找,但是在右侧寻找的话就已经不在是寻找第k小的数据了,而是寻找第(k-i-1)小的数据,所有答案应该是return quick_select(a, i + 1, r, k-(i-l+1)); //填空
这几天想想就开心的事情恐怕就是快排都不会的情况下还水进了国赛,还能去北京旅游/血赚✌
刚了解完快排的基本思想,找了个题练下手,杭电 hdu6058 然后现在一直超时是什么梗😂,百度见。
原来这是暴力枚举,那晚些复习到那里在来
#include<cstdio> #include<cstdlib> #include<iostream> using namespace std; int a[500005], ca[500005]; int quick_sort(int low, int high, int k) { //cout << low << " \t" << high << " \t" << k << endl; if (high < low || high - low + 1 < k)return 0; int s = low, e = high; int key = ca[s]; while (s < e){ while (s < e && ca[e] <= key) e--; ca[s] = ca[e]; while (s < e && ca[s] >= key) s++; ca[e] = ca[s]; } ca[s] = key; if (s - low + 1 == k)return ca[s]; if (s - low + 1 > k)return quick_sort(low, s - 1, k); else return quick_sort(s + 1, high, k - s + low - 1); } int main() { int t; cin >> t; while (t--){ int n, k; cin >> n >> k; for (int i = 1; i <= n; i++) cin >> a[i]; int sum = 0; for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++){ for (int q = 1; q <= n; q++) ca[q] = a[q]; sum += quick_sort(i, j, k); } cout << sum << endl; } return 0; }