题目描述
快速排序 - 蓝桥云课 (lanqiao.cn)
#include <stdio.h>int quick_select(int a[], int l, int r, int k) {int p = rand() % (r - l + 1) + l;int x = a[p];{int t = a[p]; a[p] = a[r]; a[r] = t;}int i = l, j = r;while(i < j) {while(i < j && a[i] < x) i++;if(i < j) {a[j] = a[i];j--;}while(i < j && a[j] > x) j--;if(i < j) {a[i] = a[j];i++;}}a[i] = x;p = i;if(i - l + 1 == k) return a[i];if(i - l + 1 < k) return quick_select( _____________________________ ); //填空else return quick_select(a, l, i - 1, k);
}int main()
{int a[100];int n;scanf("%d %d",&n);for(int i=0;i<n;i++)scanf("%d",&a[i]);printf("%d\n", quick_select(a, 0, n-1, 5));return 0;
}
题目分析
对于此题首先需要了解快速排序,简单概述如下:
给出两个指针,分别在数组的左端点与右端点,两个指针分别向中间移动,如果大小的相对位置相反了就交换这两个数,如果两指针相遇就分别左右再次递归来交换数。
在本题中,需要进行的填空为对于右边递归的判断,此时前i - l + 1个数已经过去,所以在后半部分求整体第k小的数的时候需要减去前i - l + 1个数,也就是此时求此段的第k - (i - l + 1)个数
#include <stdio.h>int quick_select(int a[], int l, int r, int k) {int p = rand() % (r - l + 1) + l;int x = a[p];{int t = a[p]; a[p] = a[r]; a[r] = t;}int i = l, j = r;while(i < j) {while(i < j && a[i] < x) i++;if(i < j) {a[j] = a[i];j--;}while(i < j && a[j] > x) j--;if(i < j) {a[i] = a[j];i++;}}a[i] = x;p = i;if(i - l + 1 == k) return a[i];if(i - l + 1 < k) return quick_select( a, i + 1, r, k - (i - l + 1)); //填空else return quick_select(a, l, i - 1, k);
}int main()
{int a[100];int n;scanf("%d %d",&n);for(int i=0;i<n;i++)scanf("%d",&a[i]);printf("%d\n", quick_select(a, 0, n-1, 5));return 0;
}