1.实践题目名称:找第k小的数;
2.问题描述:在n个无序的整数中找到第k小的数(1<=n<=1000),要求用平均时间为O(n)的算法;
3.算法描述:主要是由,主函数,partition函数,find函数,这三个函数组成
#include<iostream>
using namespace std;
int paritition(int *a, int left, int right)
{//partition的功能是将数组进行划分,使得x左侧的数都小于x且x右侧的数都大于x
int i = left, j = right+1;
int x = a[left];
while(1)
{
while(a[++i] < x&&i < right);
while(a[--j] > x);
if(i >= j)
{
break;
}
swap(a[i], a[j]);
}
a[left] = a[j];
a[j] = x;
return j;
}
void find(int *a,int left,int right,int k)
{//find的功能是通过调用partition获得一个划分点,然后判断划分点是否第k小,若不是则递归调用find继续查找
int mid = paritition(a,left,right);
if(mid == k-1)
{
cout<<a[mid];
}
else if(mid>k-1)
{
find(a,left,mid-1,k);
}
else{
find(a,mid+1,right,k);
}
}
int main()
{
int n,k;
cin>>n>>k;
int a[10000];
for(int i=0;i<n;i++)
{
cin>>a[i];
}
find(a,0,n-1,k);
return 0;
}
4.算法时间及空间复杂度分析:
时间复杂度:运用了分治法和快速排序法。用数组中的元素x对数组进行划分,分成左右两个区域,判断x是否为第k小的数,若是,则输出,若不是继续划分查找,平均时间复杂度则为O(n)
空间复杂度:find函数运用了递归,空间复杂度为O(logn)
5.心得体会:
通过本次实践学会了运用partition函数,以及在使用中要注意paritition函数的while循坏里数组元素与划分点的判断,注意符号的大于小于。
浙公网安备 33010602011771号