第二章实验报告

实践题目名称:找第k小的数

1.问题描述:

设计一个平均时间为O(n)的算法,在n(1<=n<=1000)个无序的整数中找出第k小的数。

提示:函数int partition(int a[],int left,int right)的功能是根据a[left]~a[right]中的某个元素x(如a[left])对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数。因此可以编制int find(int a[],int left,int right,int k)函数,通过调用partition函数获得划分点,判断划分点是否第k小,若不是,递归调用find函数继续在左段或右段查找。

输入格式:

输入有两行:

第一行是n和k,0<k<=n<=10000

第二行是n个整数

输出格式:

输出第k小的数

输入样例:

在这里给出一组输入。例如:

10 4

2 8 9 0 1 3 6 7 8 2

输出样例:

在这里给出相应的输出。例如:

2

算法描述:

题设提示使用快速排序,在总共有x个数的时候,每层递归时所选取的参照数在该层递归排序完后,其必定位于次数列第y个空间,前面y-1个数都比它小,后面x-y个数都大于它,即为它即是该数列中第y小的数。因此只需在快速排序的过程中找到在排序后位于第k个空间的参照数,这个数即为我们所要求的第k小的数。

 

 1 #include<bits/stdc++.h>

 2 using namespace std;

 3

 4 int partition(int a[],int left,int right){

 5     int l=left,r=right+1;

 6     int x=a[left],s;

 7     while(l<r){

 8         while(a[++l]<x&&l<r);

 9         while(a[--r]>x);

10         if(l>=r)break;

11         swap(a[l],a[r]);

12     }

13     a[left]=a[r];

14     a[r]=x;

15     return r;

16 }

17

18 int find(int a[],int left,int right,int k){

19     if(left<=right){

20         int m=partition(a,left,right);

21         if(m==k)return a[m];

22         if(m>k){

23             find(a,left,m-1,k);

24         }

25         else find(a,m+1,right,k);

26     }

27 }

28

29 int main(){

30     int n,k,a[10002];

31     cin >> n >> k;

32     for(int i=1;i<=n;i++){

33         cin >> a[i];

34     }

35     int result = find(a,1,n,k);

36     cout << result;

37     return 0;

38 }

 

2.算法时间及空间复杂度分析(要有分析过程):

设算法的复杂度为T(N),

第一步分解为两个子问题为O(1)

第二步分别求解两个子问题为O(N/2)*2

第三步合并子问题为O(N)

等式为:T(N)=O(1)+2T(N/2)+O(N)

得:T(N)=O(nlogn);

心得体会(对本次实践收获及疑惑进行总结)

实验的目的是运用快速排序算法进行第k小的数的查找,虽然运用快速排序算法的思想,但却并不完全相同,能够帮助我们复习掌握快速排序算法的同时,又发现学习到一些新的东西,举一反三。

 

posted @ 2020-10-03 22:31  楠木阁子  阅读(121)  评论(0编辑  收藏  举报