OJ--2.4--Divide and conquer method -- before K big

OJ—2.4 分治:前K大

总时间限制:
10000ms
单个测试点时间限制:
1000ms
内存限制:
65536kB

	描述
	给定一个数组,统计前k大的数并且把这k个数从大到小输出。

			
			
	输入
	第一行包含一个整数n,表示数组的大小。n < 100000。
        第二行包含n个整数,表示数组的元素,整数之间以一个空格分开。每个整数的             绝对值不超过100000000。
        第三行包含一个整数k。k < n。
	输出
	从大到小输出前k大的数,每个数一行。
	样例输入
	10
    4 5 6 9 8 7 1 2 3 0
    5
	样例输出
	9
    8
    7
    6
    5

方法是 :

快速排序 + sort

快速排序 + sort函数:

菜鸟教程–快速排序教学

用sort函数的原因是因为 如果只用快速排序的话 时间还是太长 所以我们缩短时间的方法是 :

只要找到某一个轴点 它左边所有元素的值小于他 右边所有元素的值都大于他 而 右边的元素个数恰好为 K 时我们就可以 结束快速排序了 然后用sort函数进行升序排序 记得头文件 algorithm

而这里我们只需要用sort(a,a+10); (int a[10]😉 也就是要注意左边的确是从下标开始但是右边为下标+1.

以下为我写的代码:

#include <iostream>
#include <algorithm>

using namespace std;

void quick_sort ( int a[], int l, int r, int k ) // 请注意这里要是返回值
//为void,不要想着返回轴点的下标 没有必要 一开始就知道了 就是K 如果使返回值为
//int也不对 因为那么每一个quick_sort都有一个return 那么也不能通过if来实现返
//回轴点

{
if( r > l ) {
       int i = l;
       int j = r;
       int x = a[i];
       while ( i < j ) {
            while( i < j && x <= a[j] ) {
            j--;
            }
            if( i < j ) a[i++] = a[j];
            
            while( i < j && x >= a[i] ) {
            i++;
            } 
            if( i < j ) a[j--] = a[i];
            }
            a[i] = x;
       
            if( r - i + 1 == k ) reurn;
            else {
                    quick_sort(a,l,i-1,k);
                    quick_sort(a,i+1,r,k);
            }
       }
   }
    
   int main()

  {
  int n=0;
  int k=0;
  
  cin >> n;
  int aim_array[n];
  
  for( int i=0; i < n; i++ ) {
  cin >> aim_array[i];
  }

  cin >> k;
  
  quick_sort( aim_array, 0 , n-1, k );
  sort( aim_array+n-k ,aim_array+n);

  for(int i= n-1; i >= n-k; i--) {
  cout << aim_array[i] << endl;
  } 

  return 0;
  }

/```
其实我觉得快速排序的效果是 减少了遍历和扫描的次数 至于怎么想出来的我想首先要大胆的想 
而且抓住问题的核心和目标:减少遍历和扫描的次数 还有就是要等效 怎么等效: 
每一个数最后回到自己应该的位置 , 不要有惯性的思维 , 
它是怎么减少遍历和扫描的次数与范围, 
1. 通过轴点
2. 从前和往后依次找,然后缩小范围
3. 而且我们每次遍历去找 小于或者大于 轴点的数 只要 扫描 轴点两侧任意一边即可
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页