算法第二章上机实践报告

  1. 实践题目名称:找第k小的数
  2. 问题描述:输入两个整数n和k,再输入n个乱序排序的整数;输出n个整数中第k小
  3. 算法描述: 
    主要由三个函数组成:主函数,partition以及find函数
    #include<iostream>
    using namespace std;
    
    int paritition(int *a,int left,int right)
    {//定位基准下标 返回对应划分点下标
     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)
    {//找第k小 
     int mid = paritition(a,left,right);//获取划分点下标 
     
     //比较划分点下标与k-1的大小 
     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. 时间空间复杂度分析
    最坏情况下,每次划分点为最小值或最大值,需循环k次或n-k次,时间复杂度为O(n^2);
    此算法使用递归,最好情况下空间复杂度为O(logn),最坏情况下需递归n-1次,空间复杂度为O(n)
  5. 心得体会(对本次实践收获及疑惑进行总结)
    一般情况下,看到这道题,第一反应直接排序完毕;
    快排在上学期就是简单了解原理没有特别去注意代码实现,收获大概就是快排的代码实现
    如果只是利用快排排序再来输出是不够简便的,将快排与二分法相结合能更好的解决。
    需要特别注意的大概就是paritition函数的while循坏里数组元素与划分点的判断,注意符号的大于小于,很可能最后输出的是第k大数。
posted @ 2020-10-02 14:47  蔡晓娜  阅读(182)  评论(0编辑  收藏  举报