算法第二章上机实践报告

算法第二章上机实验报告

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

2.问题描述:输入一个数组和一个整数k,找出这个数组中第k小的数。且算法时间复杂度为O(n)

3.算法描述:由函数int partition(int a[],int left,int right)int find(int a[],int left,int right,int k)int main()构成。

1partition的功能是将数组进行划分,使得x左侧的数都小于xx右侧的数都大于x

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

将最左边的数值赋给x;

while(left<right){

while下标为right的数值大于或等于x

right左移;

交换下标为leftright的数值;

while下标为left的数值小于于或等于x

left右移;

交换下标为leftright的数值;

}

重新赋值x;

返回left;

}

2find的功能是通过调用partition获得一个划分点,然后判断划分点是否第k小,若不是则递归调用find继续查找。

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

调用partition函数,赋值于变量p;

如果k-1等于p 输出下标为k-1的数值;

如果k-1小于p 递归调用findleft,p-1间继续找;

如果k-1大于p 递归调用findp+1,right间继续找;

return 0;

}

3main函数。

int main(){

定义变量n,k;

输入n,k的值;

定义一个大小为1000的数组;

for循环依次输入数组a;

调用find函数n-1,k间找;

return 0;

}

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

时间复杂度:拿到这道题想到的最直接的方法就是直接排序然后输出第k小的数,但是因为题目要求设计一个平均时间O(n)的算法,所以以上方法不可行。因此还是得用分治法。先用数组中的元素x对数组进行划分,然后判断x是否为题目要求的第k小的数,若是则输出,否则继续划分查找。这样一来就能达到题目要求的平均时间O(n)了。

空间复杂度:find函数中用到递归,空间复杂度应为O(log n)

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

本次实践学会了用partition对数组进行划分,相比于以往的直接排序后输出的较为简单粗暴的算法,这一次在题目的要求之下体会到了用更加精巧的算法去解题。

实践过程中一开始对find函数的设计不太了解,有点被卡住。递归调用还有区域的划分,后来想出来了才发现其实并不难。

posted @ 2020-10-01 14:59  陈億谋  阅读(157)  评论(0)    收藏  举报