写这个的目的在于,说明快速排序的灵活运用。我们来看下关于快速排序中的一部分关键代码:

快速排序代码:
  1. int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
  2. void quicksort(int left,int right)
  3. {
  4. int i,j,t,temp;
  5. if(left>right)
  6. return;
  7. temp=a[left]; //temp中存的就是基准数
  8. i=left;
  9. j=right;
  10. while(i!=j)
  11. {
  12. //顺序很重要,要先从右边开始找
  13. while(a[j]>=temp && i<j)
  14. j--;
  15. //再找右边的
  16. while(a[i]<=temp && i<j)
  17. i++;
  18. //交换两个数在数组中的位置
  19. if(i<j)
  20. {
  21. t=a[i];
  22. a[i]=a[j];
  23. a[j]=t;
  24. }
  25. }
  26. //最终将基准数归位
  27. a[left]=a[i];
  28. a[i]=temp;
  29. quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程
  30. quicksort(i+1,right);//继续处理右边的 ,这里是一个递归的过程
  31. }

我们抽出关键部分来分析;
    1. int partition_quickSort(int *arr,int start,int end)

    {

  1. int cmp_val=arr[start];
  2. int i=start;
  3. int j=end;
  4. while(i!=j){
  5. while(i<j&&arr[j]>=cmp_val){
  6. j--;
  7. }
  8. while(i<j&&arr[i]<=cmp_val){
  9. i++;
  10. }
  11. if(i<j){
  12. int ex_temp=arr[j];
  13. arr[j]=arr[i];
  14. arr[i]=ex_temp;
  15. }
  16. }
  17. arr[start]=arr[i];
  18. arr[i]=cmp_val;
  19. return i;
  20. }
这代部分代码的功能就是:





那么返回值的
  1. int partition_quickSort(int *arr,int start,int end)
 代表的意思是,返回值左边的数都小于返回值,而返回值右边的数都大于返回值。于是我们就可以利用这个性质来解决问题了。
对于这个问题,数组中出现次数超过一半的数字,也就是说在排好序的该数组中,那么该数组中点的元素一定是所求的结果,
但是我们有必要进行对数组进行排序吗? 答案是否
我们利用刚刚那个快速排序的性质,其返回值左边的数小于他,返回值右边的数大于他,(返回值是数组的一个小标)。
因此只要我们的返回值正好是数组的中点,也就是对应的该元素是排好序的该数组的中点,因为该数组左边的值小于它,右边
的值大于它。
如何使该函数的返回值恰 好是数组的中点呢(array.length/2)?
  1. int moreThanHalfNum_Partition(int *arr,int Length){
  2. if(arr==NULL||Length==0){
  3. return 0;
  4. }
  5. int low=0;
  6. int high=Length-1;
  7. int mid=Length>>1;
  8. int index= partition_quickSort(arr,low,high);
  9. while(index!=mid){
  10. if(index>mid){
  11. index= partition_quickSort(arr,low,index-1);
  12. }else{
  13. index= partition_quickSort(arr,index+1,high);
  14. }
  15. }
  16. int key=arr[mid];
  17. if(isMoreHalf(arr,Length,key)){
  18. return key;
  19. }else{
  20. return 0;
  21. }
  22. }
上面的思路是,如果该函数的返回值位于“中点”右边,也就是
  1. index>mid
那么可知,还是那么个性质,该数组下标小于index的值都小于index对应的元素,该数组下标大于index的值都大于index对应的值。于
是我们的中点肯定位于index左边啦。于是

  1. index= partition_quickSort(arr,low,index-1);
同理否则:

  1. index= partition_quickSort(arr,index+1,high);

还是利用快速排序的性质
  1. int partition_quickSort(int *arr,int start,int end){
  2. int cmp_val=arr[start];
  3. int i=start;
  4. int j=end;
  5. while(i!=j){
  6. while(i<j&&arr[j]>=cmp_val){
  7. j--;
  8. }
  9. while(i<j&&arr[i]<=cmp_val){
  10. i++;
  11. }
  12. if(i<j){
  13. int ex_temp=arr[j];
  14. arr[j]=arr[i];
  15. arr[i]=ex_temp;
  16. }
  17. }
  18. arr[start]=arr[i];
  19. arr[i]=cmp_val;
  20. return i;
  21. }
这是返回的值的下标左边的元素都小于它的值,下标右边的值的大于它的值,因此只要该函数返回k-1就行了。于是
  1. bool minKDataBeforeArr(int *arr,int Length,int k_bef){
  2. if(arr==NULL||k_bef>Length){
  3. return false;
  4. }
  5. int start=0;
  6. int k_index=0;
  7. int end=Length-1;
  8. k_index=partition_quickSort(arr,start,end);
  9. while(k_index!=k_bef-1){
  10. if(k_index>k_bef-1){
  11. end=k_index-1;
  12. k_index=partition_quickSort(arr,start,end);
  13. }else{
  14. start=k_index+1;
  15. k_index=partition_quickSort(arr,start,end);
  16. }
  17. }
  18. for(int i=0;i<k_bef; i++){
  19. for(int j=k_bef;j<Length; j++){
  20. if(arr[i]>arr[j]){
  21. return false;
  22. }
  23. }
  24. }
  25. return true;
  26. }
 


求出数组前面k个元素或数组中元素大于一半的元素(快速排序与堆排序的灵活运用)的更多相关文章

  1. 使用jQuery匹配文档中所有的li元素,返回一个jQuery对象,然后通过数组下标的方式读取jQuery集合中第1个DOM元素,此时返回的是DOM对象,然后调用DOM属性innerHTML,读取该元素 包含的文本信息

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 从N个元素的集合中随机取m个元素的算法实现

    最近有一个需求,比较简单,就是如标题所说的,从N个元素中随机取m个元素,当然这m个元素是不能存在重复的.本以为这么简单的需求,应该有现成的工具类来实现,但是几次查找居然没找到(有知道的可以推荐下哈^_ ...

  3. Js/Jquery获取iframe中的元素 在Iframe中获取父窗体的元素方法

    在web开发中,经常会用到iframe,难免会碰到需要在父窗口中使用iframe中的元素.或者在iframe框架中使用父窗口的元素 js 在父窗口中获取iframe中的元素  1. 格式:window ...

  4. 定义抽象类Shape,抽象方法为showArea(),求出面积并显示,定义矩形类Rectangle,正方形类Square,圆类 Circle,根据各自的属性,用showArea方法求出各自的面积,在main方法中构造3个对象,调用showArea方法。(体现多态)

    实现多态的三个条件:1.要有继承2.要有抽象方法重写3.用父类指针(引用)指向子类对象 重载重写重定义的区别: 1.重载:在同一个类中进行; 编译时根据参数类型和个数决定方法调用; 子类无法重载父类; ...

  5. 输出数组第k大的元素

    用快速排序的思想输出数组第k大的元素: #include<iostream> #include<algorithm> using namespace std; //递归实现:返 ...

  6. 一个字符串中可能包含a~z中的多个字符,如有重复,如String data="aavzcadfdsfsdhshgWasdfasdf",求出现次数最多的那个字母及次数,如有多个重复的则都求出。

    主要掌握String中的方法 char[] toCharArray()           将此字符串转换为一个新的字符数组. int indexOf(String str)           返回 ...

  7. CSS中伪类及伪元素用法详解

    CSS中伪类及伪元素用法详解   伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...

  8. CSS中2d转换:transition过渡放在:hover伪类中与应用在整个元素中区别

    css的2d转换十分强大,能够在不使用js的情况下,实现页面的元素与用户之间更多动态的交互,增强用户体验.其中使用最多的就是hover伪类. 1.创建一个页面的div元素: <!DOCTYPE ...

  9. 如何求出数组中最小(或者最大)的k个数(least k问题)

    输入n个整数,如何求出其中最小的k个数? 解法1. 当然最直观的思路是将数组排序,然后就可以找出其中最小的k个数了,时间复杂度以快速排序为例,是O(nlogn): 解法2. 借助划分(Partitio ...

随机推荐

  1. Mysql-学习笔记(==》触发器 十一)

    -------触发器-------- USE db;SELECT FROM sss; CREATE TABLE sssbak LIKE sss;SHOW CREATE TABLE sss;SHOW C ...

  2. Windows 多线程知识点汇总

    一.什么叫原子性? 答:一个操作不会被分成两个时间片来执行,不会刚执行到一半,由于时间片到了,CPU就跑去执行其他线程了.在多线程环境中对一个变量进行读写时,我们需要有一种方法能够保证对一个值的操作是 ...

  3. sysbench 0.5 oltp测试笔记

    sysbench 0.5相比0.4版本的主要变化是,oltp测试结合了lua脚本,不需要修改源码,通过自定义lua脚本就可以实现不同业务类型的测试.同时0.5相比0.4需要消耗更多的cpu资源. 1. ...

  4. Python3基础 用三个双引号 print输出多行文本

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  5. BZOJ 2324 营救皮卡丘(最小费用最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2324 题意:n+1个城市(0到n).初始时K个 人都在0城市.城市之间有距离.要求(1) ...

  6. c++ 动态分配二维数组 new 二维数组

    #include "stdafx.h" #include <iostream> using namespace std; int _tmain(int argc, _T ...

  7. Java——再看IO

    一.编码问题 utf-8编码中,一个中文占3个字节,一个英文占1个字节:gbk编码中,一个中文占2个字节,一个英文占1个字节. Java是双字节编码,为utf-16be编码,是说一个字符(无论中文还是 ...

  8. Beaglebone Black– 智能家居控制系统 LAS - 刷 WiFi 模块 ESP8266 Firmware 和 ESP8266 直接收发 GPIO 信号

    用 Windows 来刷 ESP8266 固件有很多中文教程,来试试直接用 BBB 刷吧.目标是 NodeMCU,ESP-01 可用,就是我买的那个. 接线方式在上一篇.当 echo ‘BB-UART ...

  9. 如何在VirtualBox虚拟机软件上安装Win7虚拟系统

    在Windows系统中安装VirtualBox 双击从官网上下载的VirtualBox-4.3.12-93733-Win.exe安装程序,默认下一步,下一步完成基础安装. 在VirtualBox虚拟机 ...

  10. POJ-2175 Evacuation Plan 最小费用流、负环判定

    题意:给定一个最小费用流的模型,根据给定的数据判定是否为最优解,如果不为最优解则给出一个比给定更优的解即可.不需要得出最优解. 解法:由给定的数据能够得出一个残图,且这个图满足了最大流的性质,判定一个 ...