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

 #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. 编译sass,遇到报错error style.scss (Line 3: Invalid GBK character "\xE5")

    今天学习sass,写了一行中文注释,结果却遇到了报错: cmd.exe /D /C call C:/Ruby23-x64/bin/scss.bat --no-cache --update style. ...

  2. 十、jdk工具之Jdb命令(The Java Debugger)

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

  3. [转]Web前端浏览器兼容

    转自: http://www.admin10000.com/document/1900.html 前言 浏览器兼容是前端开发人员必须掌握的一个技能,但是初入前端的同学或者其他后台web开发同学往往容易 ...

  4. pyinstaller的使用方法 by 王大龙

    ---------------------------------------------------------------------------------------------------- ...

  5. 我的solr学习笔记--solr admin 页面 检索调试

    前言 Solr/Lucene是一个全文检索引擎,全文引擎和SQL引擎所不同的是强调部分相关度高的内容返回,而不是所有内容返回,所以部分内容包含在索引库中却无法命中是正常现象.      多数情况下我们 ...

  6. sql多表更新使用别名(小技巧)

    update     A set     A.CityRegionID=B.ParentID,     A.CityName=(select RegionName from Common_Region ...

  7. grunt 不是内部或外部命令,也不是可运行的程序或批处理文件

    问题1 grunt 不是内部或外部命令,也不是可运行的程序或批处理文件 解决方法: Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. 安装CLI 在继 ...

  8. SecureCRT 8.1使用经验总结

    1.反空闲设置: 2.文件上传下载 上传 sudo rz -y 文本文件勾选Upload files as ASCII,图片或其他飞文本文件,去掉勾选.采用默认binary 3.文件下载 sudo s ...

  9. Servlet类源码说明

    servlet是学习java web不可不懂的一个类,网上各种教程都参杂太多,每次理解都感觉像把别人吐出来的食物再放在嘴里咀嚼,小编一怒之下,直接打开源码,原汁原味的芬芳扑面而来: /** * Def ...

  10. FoxPro 游标指针操作

    查询上一记录skip -1 *相对定位 指针向上移动一条记录if bof() *测试当前记录指针是否超出第一条记录  go top *绝对定位表的第一条记录endifthisform.refresh ...