这是一道很经典的题目,有太多方法了,今天写了两种方法,分别是快排和堆排序

 #include <iostream>
using namespace std;
#define N 25 //初始化数组
//int a[] = {6, 2, 3, 9, 4, 3, 1, 2, 4, 4};
//int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int a[] = {, , , , , };
int n = ;
int K = ; //快速排序,o(nlogn),最应该想到的思路,排好序要多大数就输出多大数
/*
partition就是挖第一个洞,从后往前找,找到,挖起来,把前面的洞埋上,再从前往后找,找到,挖起来,把后面的洞埋上,直到最后,high=low了,把这个洞补上
*/
int partition(int* p, int low, int high)
{
int i;
int pivot;
//把第一个数拿出来,挖个洞
pivot = p[low];
while (low < high)
{
//从后往前找,找到比pivot小的值
while (low < high && p[high] >= pivot)
high--;
//然后后面的数埋上前面的洞
//Note这里无须再加个if,因为即使相同了,那我再做一步也无妨,而且也无须把low指针往上移,因为,到时候我可以再判断一次,还是可以移动的
p[low] = p[high]; //从前往后找,找到比pivot大的值,然后把前面的数埋上
while (low < high && p[low] <= pivot)
low++;
p[high] = p[low];
}
//这里low和high已经相同了,所以也可以写成p[high]=pivot,这一步就是把洞埋上
p[low] = pivot;
return low;
}
/*
其实,两个可以写一起,但是,分开写更清楚
quickSort函数就是当low<high时,进行一次partition,然后再对分开的两块进行quickSort
*/
void quickSort(int* p, int low, int high)
{
if(low < high)
{
int breakpoint = partition(p, low, high);
quickSort(p, low, breakpoint - );
quickSort(p, breakpoint + , high);
}
} //堆排序, o(nlogk),考虑到只需取K大的数,那就无须对n个数都排序,只需记录下k个即可
int heap[N];
/*
//这里有点疑问哦,考虑到heap数组可能比较大,所以想定义成全局变量,可是这样就不必传递参数勒,定义成局部变量,参数又太多
目前定义成全局变量
input: lastIndex指heap数组要插入的value的位置(是要插入的位置哦); value指要插入的数字
function: heap数组是从index=0开始储存的,就是把value储存heap数组内,并进行相应的调整,符合最大堆的性质
*/
void MaxHeapPush(int lastIndex, int value)
{
//把value放在堆的末尾
heap[lastIndex] = value;
//记录下末尾的index
int index = lastIndex;
// 不断向上调整
while (index)
{
//若比上面的大,就交换
if (heap[index] > heap[(index - ) / ])
{
int temp = heap[index];
heap[index] = heap[(index - ) / ];
heap[(index - ) / ] = temp;
}
//否则,说明已经调整好了,立即停止
else
break;
//若没有break出来,就要一直调整了,所以index要变动
index = (index - ) / ;
}
}
/*
input:
p数组要初始化数组,提供数据的
n表示该数组的长度,c就是麻烦,连长度都要传入
heapSize表示要维护的堆的大小,Note,一定要大于K哦
*/
void MaxHeapInit(int *p, int n, int heapSize)
{
int i, lastIndex;
lastIndex = ;
for (i = ; i < n; i++)
{
//依次插入
MaxHeapPush(lastIndex, p[i]);
// 若比预定好的堆的大小小的话,最后一个value的值就要增加了
if (lastIndex < heapSize)
lastIndex++;
}
} /*
input: lastIndex是要删除的value的位置(这里千万要注意,其实,跟前面的lastIndex有点不一样)
*/
int MaxHeapPop(int lastIndex)
{
// 交换头尾value
int temp, i;
temp = heap[];
heap[] = heap[lastIndex];
heap[lastIndex] = temp;
// 向下调整
i = ;
int child = * i + ;
while (child < lastIndex)
{
//若有右孩子节点,且右节点比左节点大,那要只需要比较右节点即可
if (child + < lastIndex && heap[ * i + ] > heap[ * i + ])
{
child = child + ;
}
//若孩子节点比父节点大,两个节点交换
if (heap[child] > heap[i])
{
temp = heap[child];
heap[child] = heap[i];
heap[i] = temp;
}
//否则说明已经有序,停止
else
break;
// 变化孩子节点的index
child = * i + ;
}
// 返回末尾value
return heap[lastIndex];
} int main()
{
int i, j;
for (i = ; i < n; i++)
cout<<a[i]<<" ";
cout<<endl;
/*
//快排,若取前K大的数,只需从末尾到前输出K个数即可
quickSort(a, 0, n - 1);
for (i = 0; i < n; i++)
cout<<a[i]<<" ";
cout<<endl;
*/ //注意这里之所以乘以2,是因为只维护K个数字的堆,不能得到前K个大的数!!
MaxHeapInit(a, n, K * - );
for (i = ; i < n; i++)
cout<<heap[i]<<" ";
cout<<endl; // 输出,这里的lastIndex是变化的哦,因为之前维护的2 * K - 1的堆,所以这里也应该是2 * K - 1
for (i = ; i < K; i++)
cout<<MaxHeapPop( * K - - i)<<" ";
cout<<endl; system("pause");
return ;
}

寻找最大的K个数(上)的更多相关文章

  1. 算法系列:寻找最大的 K 个数

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  2. 第2章 数字之魅——寻找最大的K个数

    寻找最大的K个数 问题描述 在面试中,有下面的问答: 问:有很多个无序的数,我们姑且假定它们各不相等,怎么选出其中最大的若干个数呢? 答:可以这样写:int array[100] …… 问:好,如果有 ...

  3. O(N)的时间寻找最大的K个数

    (转:http://www.cnblogs.com/luxiaoxun/archive/2012/08/06/2624799.html) 寻找N个数中最大的K个数,本质上就是寻找最大的K个数中最小的那 ...

  4. 03寻找最小的k个数

    题目描述:查找最小的k个元素         题目:输入n个整数,输出其中最小的k个.         例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 1:最简单 ...

  5. 算法练习:寻找最小的k个数

    参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...

  6. 编程之美2.5:寻找最大的K个数

    编程之美2.5:寻找最大的K个数 引申:寻找第k大的数: 方法一: // 选择第k大的数(通过改进快速排序来实现) public static void SelectShort(int[] array ...

  7. 寻找最大的k个数问题

    这是编程之美书第2.5节的一道题目. 各种解法: 解法一,用nlgn复杂度的排序算法对数组进行从大到小排序,取前K个.但这方法做了两件不必要做的事:它对想得到的K个数进行了排序,对不想得到的n-K个数 ...

  8. 算法笔记_035:寻找最小的k个数(Java)

    目录 1 问题描述 2 解决方案 2.1 全部排序法 2.2 部分排序法 2.3 用堆代替数组法 2.4线性选择算法   1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 ...

  9. Java实现寻找最小的k个数

    1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 解决方案 2.1 全部排序法 先对这n个整数进行快速排序,在依次输出前k个数. package com.liuzhen. ...

随机推荐

  1. 【python】使用Python中的urlparse、urllib抓取和解析网页

    一.解析URL 函数urlparse(urlstring [, default_scheme [, allow_fragments]])的作用是将URL分解成不同的组成部分,它从urlstring中取 ...

  2. ReportViewer 2010 打印预览,用鼠标快速切换显示比例时报错:存储空间不足,不能处理此命令

    CreateCompatibleDIB 存储空间不足 无法处理此命令 安装 ReportViewer 2010 sp1 即可.

  3. C语言 字符串处理函数 转自 http://blog.chinaunix.net/uid-25885064-id-3175049.html

     C字符串处理函数 2012-04-13 18:14:16 分类: C/C++ void *memccpy (void *dest, const void *src, int c, size_t n) ...

  4. Data_Structure03-栈和队列

    一.学习总结 1.写出你认为本周学习中比较重要的知识点关键词 ·抽象数据类型 ·栈和队列 2.思维导图 二.PTA实验作业 选题: 1.7-1 jmu-字符串是否对称(20 分) 2.7-4(选做) ...

  5. 深入浅出HTTPS工作原理(转载)

    转载自: https://blog.csdn.net/wangtaomtk/article/details/80917081 深入浅出HTTPS工作原理 HTTP协议由于是明文传送,所以存在三大风险: ...

  6. Restful&RestSharp

    RestSharp 一个.NET(C#)的HTTP辅助类组件 https://www.cnblogs.com/lilunjia/p/7090015.html C#使用RestSharp实现post发送 ...

  7. 正规式->最小化DFA说明

      整体的步骤是三步: 一,先把正规式转换为NFA(非确定有穷自动机), 二,在把NFA通过"子集构造法"转化为DFA, 三,在把DFA通过"分割法"进行最小化 ...

  8. 《OpenCL异构并行编程实战》第十二至十四章

    ▶ 第十二章,在其他语言中使用 OpenCL ● JOCL(Java Building for OpenCL),PyOpenCL ● 一个 PyOpenCL 的例子代码,需要 pyopencl 包 i ...

  9. MPI 派生数据类型 MPI_Type_create_struct(),MPI_Type_contiguous(),MPI_Type_vector(),MPI_Type_create_hvector(),MPI_Type_indexed()

    ▶ 使用 MPI 派生数据类型,减少数据在传输过程中的耗时 ● MPI_Type_create_struct() 范例代码 { ; int globalDataInt[globalSize], glo ...

  10. 决策树与树集成模型(bootstrap, 决策树(信息熵,信息增益, 信息增益率, 基尼系数),回归树, Bagging, 随机森林, Boosting, Adaboost, GBDT, XGboost)

    1.bootstrap   在原始数据的范围内作有放回的再抽样M个, 样本容量仍为n,原始数据中每个观察单位每次被抽到的概率相等, 为1/n , 所得样本称为Bootstrap样本.于是可得到参数θ的 ...