算法第二章上机实践报告
算法第二章上机实验报告
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()构成。
(1)partition的功能是将数组进行划分,使得x左侧的数都小于x且x右侧的数都大于x。
int partition(int a[],int left,int right){
将最左边的数值赋给x;
while(left<right){
while下标为right的数值大于或等于x
right左移;
交换下标为left和right的数值;
while下标为left的数值小于于或等于x
left右移;
交换下标为left和right的数值;
}
重新赋值x;
返回left;
}
(2)find的功能是通过调用partition获得一个划分点,然后判断划分点是否第k小,若不是则递归调用find继续查找。
int find(int a[],int left,int right,int k){
调用partition函数,赋值于变量p;
如果k-1等于p 输出下标为k-1的数值;
如果k-1小于p 递归调用find在left,p-1间继续找;
如果k-1大于p 递归调用find在p+1,right间继续找;
return 0;
}
(3)main函数。
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函数的设计不太了解,有点被卡住。递归调用还有区域的划分,后来想出来了才发现其实并不难。
                    
                
                
            
        
浙公网安备 33010602011771号