算法第二章上机实践报告
1.实践题目名称:
找第k小的数
2.问题描述:
设计一个平均时间为O(n)的算法,在n(1<=n<=1000)个无序的整数中找出第k小的数。
3.算法描述:
定义一个分割函数,实现返回指定数组中的数在数组中是第k大的数值k,若该k值与题目所需不符,则传入另一查找函数,在该查找函数中实现在数组的[0,k)或(k,n]段中查找符合要求的k值。函数具体实现如下:
1 //分割函数 2 3 //选取数组中的第一个数作为基数,将数组分成两部分 4 int partition(int a[],int left,int right){ 5 int i=left+1; 6 int j=right; 7 while(i<j){ 8 while(i<right&&a[i]<a[left]) i++; 9 while(a[j]>a[left]) j--; 10 if(i>=j) break; 11 swap(a[i],a[j]); 12 } 13 swap(a[j],a[left]); 14 return j; 15 } 16 17 //查找函数 18 19 int find(int a[],int left,int right,int k){ 20 int t=partition(a,left,right); 21 //递归终止条件 22 if(t==k-1) return a[t]; 23 //如果基底数经partition返回的下标比k小,则在数组左边查找 24 else if(t>k-1) find(a,left,t-1,k); 25 //否则在数组右边进行查找 26 else find(a,t+1,right,k); 27 }
4.算法时间及空间复杂度分析:
时间复杂度:每次迭代尽可能遍历数组的一半,故时间复杂度为O(n/2) + O(n/4) + O(n/8) + ... +O(1) = O(n)
空间复杂度:整个过程仅需为数组申请一次空间,故空间复杂度同样为O(n)
5.心得体会:
这次实践使得我对分治法有了更为深刻的理解,以及了解到解决实例的正确思路的思考的重要性。