问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k大的元素,(这里给定的线性集是无序的)。

  其实这个问题很简单,直接对线性序列集qsort,再找出第k个即可。但是这样的时间复杂度就是qsort的时间复杂度O(nlogn)。有没有更快的方法呢?看到网上有一种解法是采取了快排的思路,但是稍微坐了些改动,然后时间复杂度能够接近O(n)。因为最近刚刚写了快排的实现,所以在这我就再把这个实现一次吧。

  解题思路:与快排不同的是,这里只对划分出来的其中一组进行递归处理。任意选定一个pivotIndex,pivotValue = arr[pivotIndex]。经过一次划分后,pivotValue存储在storeIndex的位置,storeIndex把数组划分为两部分。比pivoteValue大的在前面,比pivotValue小的存储在后面(此时前后两部分是没有排好序的)。那么storeIndex位置的pivotValue就肯定是第storeIndex大的数。然后用K于storeIndex比较,如果K<storeIndex,那么说明第K大一定在右边,那么再对右边进行划分即可。如果K>storeIndex,那么说明第K大一定在左边,那么再对左边进行划分。然后递归,最后就可以得到第K大。

#include <stdio.h>

void swap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
} int partition(int arr[], int left, int right, int pivotIndex)
{
int storeIndex = left;
int pivotValue = arr[pivotIndex];
int i; swap(&arr[pivotIndex],&arr[right]); for (i = left; i < right; i ++)
{
if (arr[i] > pivotValue)
{
swap(&arr[i],&arr[storeIndex]);
storeIndex++;
}
}
swap(&arr[storeIndex],&arr[right]);
return storeIndex;
} int findKMax(int arr[], int left, int right, int k)
{
int nRet;
int pivotIndex = left + ; nRet = partition(arr,left,right,pivotIndex);
if (nRet < k)
{
return findKMax(arr,nRet+,right,k);
}
else if (nRet > k)
{
return findKMax(arr,left,nRet-,k);
} return nRet;
} int main()
{
int i,k,nRet;
int arr[] = {,,,,,,,}; scanf("%d",&k);
nRet = findKMax(arr,,,k-); printf("The Kth Max Number locate in %d is :%d\n",nRet,arr[nRet]);
for (i = ; i < ; i++)
{
printf("%3d",arr[i]);
}
return ;
} // :

  萧萧空间列出了很多种寻找第K大数的算法。

第二次实现该算法:

#include <stdio.h>

void swap(int arr[], int i, int j)
{
int tmp; tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
} int partition(int arr[], int left, int right)
{
int value = arr[left];
int p_insert,p_cmp; swap(arr,left,right);
p_insert = p_cmp = left; while (p_cmp < right)
{
if (arr[p_cmp] < value)
{
swap(arr,p_insert,p_cmp);
p_insert++;
}
p_cmp++;
}
swap(arr,p_insert,right); return p_insert;
} void max_k(int arr[], int left, int right,int k)
{
int ret = partition(arr,left,right);
if (ret == k) return;
else if (ret < k)
ret = partition(arr,ret+,right);
else
ret = partition(arr,left,ret);
} int main()
{
int arr[] = {,,,,,,,,};
int i,k = ; max_k(arr,,,k); for (i = ; i < k; i++)
{
printf("%d ",arr[i]);
}
printf("\n"); return ;
} // :

分治算法--寻找第k大数的更多相关文章

  1. 蓝桥杯 算法训练 区间k大数查询(水题)

    算法训练 区间k大数查询 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...

  2. 算法训练 区间k大数查询

    http://lx.lanqiao.org/problem.page?gpid=T11 算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB        问题描述 给定一个 ...

  3. 蓝桥杯--算法训练 区间k大数查询

                                                                                 算法训练 区间k大数查询   时间限制:1.0 ...

  4. 算法训练 区间K大数

    算法训练 区间k大数查询 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...

  5. 蓝桥杯算法训练 区间k大数查询

    算法训练 区间k大数查询   问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包含n个正整数,表示给定的序列. 第三个 ...

  6. P3290 寻找第K大数

    描述 寻找第K大数 N个小朋友在一起做游戏.每个小朋友在自己的硬纸板上写一个数,然后同时举起来.接着,小y老师提一个问题,看哪个小朋友先抢答出来.问题是:在这N个数中,第K大的是哪个数?请你编程完成. ...

  7. Java实现 蓝桥杯 算法训练 区间k大数

    算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二 ...

  8. 算法准备-分治算法解决第k位数的线性查找

    由作业士兵排队问题引出的 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数最表(x,y)表示.士兵可以沿着网格边上.下.左.右移动一步,但在同一时刻一个网格上只能有一名士兵.按照军官 ...

  9. 蓝桥网试题 java 算法训练 区间k大数查询

    -------------------------------------------------------------------------- 数组也有sort方法 尽量把输入和操作分开写 -- ...

随机推荐

  1. xctool + oclint 安装使用

    使用brew 安装Xctool 先跟新brew : sudo  brew update brew install xctool --HEAD OK. 使用请参照 文档 如: xctool -works ...

  2. Flex tree加三状态的Checkbox

    网上有下过其它人的实现的样例.可是样式不好改.还有就是不能初始化选中,还有三态效果那个半选中状态也是不清楚.所以自己依据Itemrender搞了一个,还凑合 效果如图:全选和半选状态,Checkbox ...

  3. 腾讯云服务器 Centos6.5 安装 nginx1.12.0

    今天买了腾讯云,不要问我为什么没有买阿里云... 入正题: 如果出现 CentOS ping: unknown host 的话,表示没有配置dns vim /etc/sysconfig/network ...

  4. Quartz 任务调度框架之Hello World

    0x01 什么是Quartz? Quartz是一个完全由java编写的开源作业调度框架. 0x02 实战Quartz Hello World 创建Maven项目,POM 文件配置如下: <pro ...

  5. Ultraedit使用小技巧

    4. 编辑文件如何加入时间戳 ?F7 快捷键即可.你试试看? 5. 为何拷贝(Copy)/粘贴(Paste)功能不能用了?不怕大家笑话,我有几次使用 UltraEdit的过程中发现拷贝与粘贴的内容是不 ...

  6. 【Unity】4.5 树木创建器

    分类:Unity.C#.VS2015 创建日期:2016-04-11 一.简介 在地形编辑器一节中,已经告诉了你如何使用已经创建好的树来形成大片树林.这一节告诉你在 Unity 5.3.4中如何利用[ ...

  7. 【设计模式】装饰器模式与Java Servlet、Spring Session在其中的使用

    简述 装饰器模式,可以通过装饰器类,通过依赖原实现的方式(不使用继承),达到扩展原实现的目的.UML图如下: ServletRequestWrapper于其中的使用 ServletRequestWra ...

  8. squid搭建http/https代理服务器

    前言:笔者使用的长城宽带,访问国外网站,比如mysql,nginx等站点的速度.......,你懂得,于是想到使用腾讯云主机搭建squid代理服务器,这里搭建的是一般代理服务器,squid代理服务器分 ...

  9. tf.nn.bias_add

    tf.nn.bias_add bias_add( value, bias, data_format=None, name=None ) 功能说明: 将偏差项 bias 加到 value 上面,可以看做 ...

  10. firefox快捷键窗口和标签类

    firefox快捷键窗口和标签类: 关闭标签: Ctrl+W 或 Ctrl+F4关闭窗口: Ctrl+Shift+W 或 Alt+F4向左移动标签: Ctrl+左方向键 或 Ctrl+上方向键向右移动 ...