一.什么是线性时间选择问题

前几天,女票问到了快速排序,然后我看了一下代码,发现不对呀,为什么连基本的递归都没有,后来仔细看了整个程序之后,发现,这个程序并不是普通的快速排序,而这也就引出了今天要讲的问题,线性时间选择问题,其实它也就是随机化的快速排序,以求加快效率,最快求解。

二.大体思路

RandomizedSelect算法,因为该算法是想要求解在一个序列中某一个等级大小的数,那么这个算法的大体思路其实就是随机选取基准元素,根据基准元素进行分区,小的分在左边,大的分在右边,每次分完之后返回基准元素所在数组中的索引,同时比较等级,小的话在左边查找,大的话在右边查找,那么这样说的话大家是不是又想到了快速排序算法,是不是特别熟悉呢。

三.具体实现

谈及具体实现的话,我还是先把代码贴上来然后一点一点地分析。

int RandomizedSelect(int a[],int low,int high,int k)
{if(low==high)return a[low];int i=RandomizedPartition(a,low,high);int j=i-low+1;if(k<=j)return RandomizedSelect(a,low,i,k);elsereturn RandomizedSelect(a,i+1,high,k-j);
}

这就是其中最核心的部分。

03,04:和快排类似,倘若low==high,那么说明基准点已经到了我们需要的等级的位置,直接返回当前值。

05:假如不相等,那么就得重新分区。

06--10:重新分区之后,就得根据基准元素返回的索引考虑接下来往哪边寻找。

接下来是随机选取基准元素的函数

int RandomizedPartition(int a[],int low,int high)
{Random rm = new Random();int i = rm.Next(low,high);Swap(a[i],a[low]);return Partition(a,low,high);
}

前两句就是在新的分区里面寻找新的随机基准点,在这里我们把随机选取的基准点和第一个元素交换,因为后面分区的时候一直以第一个元素为基准,后两句就是重新分区。

最后就是分区函数,其实这里就用到了快排

int Partition(int a[],int low,int high)
{int i=low,j=high+1;int x=a[low];while(true){while(a[++i]<x&&i<high);while(a[--j]>x);if(i>=j) break;Swap(a[i],a[j]);}a[low]=a[j];a[j]=x;return j;
}

相信这里就不用过多解释了,很容易理解。

最后附上整个实例。

#include<iostream>
#include<cstdlib>
#include<time.h>
using namespace std; void Swap(int &a,int &b)
{ int tmp=a; a=b; b=tmp;
} int Partition(int a[],int low,int high)
{  int i=low,j=high+1; int x=a[low];while(true){while(a[++i]<x&&i<high);while(a[--j]>x);if(i>=j) break;Swap(a[i],a[j]); } a[low]=a[j];a[j]=x; return j;
} int RandomizedPartition(int a[],int low,int high)
{  Random rm = new Random();int i = rm.Next(low,high);Swap(a[i],a[low]); return Partition(a,low,high);
} int RandomizedSelect(int a[],int low,int high,int k)
{ if(low==high) return a[low]; int i=RandomizedPartition(a,low,high); int j=i-low+1; if(k<=j) return RandomizedSelect(a,low,i,k); else return RandomizedSelect(a,i+1,high,k-j);
} /* 测试 */
int main()
{ int a[]={4,7,9,5,8,3,0,1}; int k=2; int result=RandomizedSelect(a,0,7,k); cout<<"第"<<k<<"小的元素是"<<result<<endl; return 0;
} 

四.总结

首先要强调的是,RandomizeSelect算法,最好能够达到O(n)的时间复杂度,这时很不错的,另外最坏也是O(n*n),而不是像一些普通算法,平均复杂度是O(n*n),其次呢,该算法跟数据的准备还是有比较大的关系的,这个我们之后再另外写一篇好好叙述。总的说来呢,我主要是看到之后耳目一新,自己实现了一下,其实我完全是算法方面的小白,如果有错误还希望指正。

email: wuzhicheng@bjfu.edu.cn

谢谢!

算法探究:线性时间选择问题相关推荐

  1. 线性时间选择-分治算法

    问题描述  给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素.在线性时间内O(n)? k=1; 最小元素 O(n) k=n; 最大元素 O(n) k=(n+1)/2: ...

  2. 线性时间选择求第k小数(分治)

    目录 线性时间选择 优化 对划分进行随机数改良 取中位数进行划分 全部代码 线性时间选择 问题描述:给定线性序集中 n 个元素和一个整数 k(1 <= k <= n),要求找出着 n 个元 ...

  3. 算法设计与分析——递归与分治策略——线性时间选择

    顾名思义:这篇文章讲解的就是如果用线性时间算法来作出元素选择问题. 问题描述:给定线性序集中n个元素和一个整数k,1<=k<=n.要求找出这n个元素中第k小的元素,即如果将这个n个元素依其 ...

  4. 算法笔记——【分治法】线性时间选择

    线性时间选择问题:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序的). 随机划分线性选择 线性时间选择随机划分法可以模仿随机化快速排序算法设 ...

  5. 搜索中常见数据结构与算法探究(二)

    本文介绍了几个常见的匹配算法,通过算法过程和算法分析介绍了各个算法的优缺点和使用场景,并为后续的搜索文章做个铺垫:读者可以通过比较几种算法的差异,进一步了解匹配算法演进过程以及解决问题的场景:KMP算 ...

  6. 分治法:线性时间选择

    大家好,我是连人,本期分享线性时间选择问题. 线性时间选择是基于快速排序的一种延申,本质上和快排具有类似的地方.它的目的是找出这个数组中第k小的值. 既然只需找出1个值,我们就不必将整个数组排序.通过 ...

  7. 【分治】线性时间选择(C++)

    一.线性时间选择 1. 问题描述 给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素. 2. 线性时间选择-随机划分 算法步骤: 生成1个随机数 i ,将数组a[p:r] ...

  8. 线性时间选择【递归分治法】

    顾名思义:这篇文章讲解的就是如果用线性时间算法来作出元素选择问题. 问题描述:给定线性序集中n个元素和一个整数k,1<=k<=n.要求找出这n个元素中第k小的元素,即如果将这个n个元素依其 ...

  9. 从零开始学数据结构和算法(二)线性表的链式存储结构

    链表 链式存储结构 定义 线性表的链式存储结构的特点是用一组任意的存储单元的存储线性表的数据元素,这组存储单元是可以连续的,也可以是不连续的. 种类 结构图 单链表 应用:MessageQueue 插 ...

  10. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

最新文章

  1. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
  2. ML之DT:利用DT(DTC)实现对iris(鸢尾花)数据集进行分类并可视化DT结构
  3. 《机器学习》 —— 第一章:绪论 学习笔记
  4. kali linux解密栅栏密码,最详细bugku加密小白解法---持续更新!
  5. 2018-2019 ACM—ICPC SEERC 题解
  6. Android Notification 手机系统横幅弹出提示框调用,横幅通知,RemoteViews使用实例
  7. android 最新功能介绍,Android Studio 常用功能介绍
  8. 系列(一):加解密字符串及配置文件(CSASPNETEncryptAndDecryptConfiguration)
  9. Tableau Desktop【包含各个版本】
  10. Fiddler2汉化版使用说明
  11. kuangbin数学训练1
  12. 2020年408真题_2020年港澳台联考真题——数学!
  13. Java自学经验分享
  14. 图像处理与机器视觉行业分析
  15. UE4家装系统工程源码/内含模型/材质/模型拖拽
  16. 蓝牙BLE设备连接与通信
  17. SpringCloud集成微信支付
  18. Linux下制作bin文件,并对其进行截取、合并、修改
  19. 使用ffmpeg批量转码的命令行(以mkv转mp4为例)
  20. musicbee歌词_MusicBee是快速而强大的音乐管理器

热门文章

  1. python——numpy——roll()函数
  2. Maven安装与配置(详细步骤)
  3. Mysql中修改字段类型、长度以及添加删除列
  4. 用slub track调试use after free问题
  5. 长虹电视刷机固件包汇总
  6. 算法速学速用大辞典 pdf_随机梯度蒙特卡洛算法-重要性采样
  7. 模拟器中安装和使用Drozer总结
  8. python模拟手机app签到_Python实现云之家自动签到
  9. JAVA代码实现下载解析网易云音乐到本地电脑的demo示例
  10. 计算机控制实验报告组态软件学习,单片机与MCGS组态综合实验系统 教学软件 实训系统...