博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线性时间选择
阅读量:6229 次
发布时间:2019-06-21

本文共 2246 字,大约阅读时间需要 7 分钟。

例子:

  • 按递增顺序,找出下面29个元素的第18个元素:8,31,60,33,17,4,51,57,49,35,11,43,37,3,13,52,6,19,25,32,54,16,5,41,7,23,22,46,29.
  • (1) 把前面25个元素分为5(=floor(29/5))组;  (8,31,60,33,17),(4,51,57,49,35),(11,43,37,3,13),(52,6,19,25,32),(54,16,5,41,7).
  • (2) 提取每一组的中值元素,构成集合{31,49,13,25,16};
  • (3) 递归地使用算法求取该集合的中值,得到m=25;
  • (4) 根据m=25, 把29个元素划分为3个子数组:

–     P={8,4,11, 3,13,6,19,16,5,7,23,22}

–     Q={25}

–     R={31,60,33,51,57,49,35,43,37,52,32,54,41,46,29}

  • (5) 由于|P|=13,|Q|=1,k=18,所以放弃P,Q,使k=18-13-1=4,对R递归地执行本算法;
  • (6) 将R划分成3(floor(18/5))组:{31,60,33,51,57},{49,35,43,37,52},{32,54,41,46,29}
  • (7) 求取这3组元素的中值元素分别为:{51,43,41},这个集合的中值元素是43;
  • (8) 根据43将R划分成3组:

–     {31, 33, 35,37,32, 41, 29},{43},{60, 51,57, 49, 52,54, 46}

 

  • (9)  因为k=4,第一个子数组的元素个数大于k,所以放弃后面两个子数组,以k=4对第一个子数组递归调用本算法;
  • (10)  将这个子数组分成5个元素的一组:{31,33,35,37,32},取其中值元素为33;
  • (11)  根据33,把第一个子数组划分成{31,32,29},{33},{35,37,41};
  • (12)  因为k=4,而第一、第二个子数组的元素个数为4,所以33即为所求取的第18个小元素。
/* * 线性选择算法 * 给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素 * 在最坏情况下,算法randomizedSelect需要O(n2)计算时间 * 可以证明,算法randomizedSelect可以在O(n)平均时间内找出n个输入元素中的第k小元素。 */代码/**递归分治算法之线性选择 */ import java.util.Random;public class randomizedSelectTest {             private static int randomizedPartition(int[] a,int p,int r){            int i=random(p,r);            swap(a,i,p);//交换枢纽元素到区间左端            return partition(a,p,r);            }              /**         * 线性选择指定数组中第k小的元素         * @param a 指定数组         * @param p 区间左端         * @param r 区间右端         * @param k 数组的大小位置         * @return 返回指定数组中第k小的元素         */        public int randomizedSelect(int[] a,int p,int r,int k){            if(p==r)return a[p];            int i=randomizedPartition(a,p,r);            int j=i-p+1;//左端元素个数            //第k小的元素在左端            if(k<=j)return randomizedSelect(a,p,i,k);            else//第k小的元素在右端,并且左端已经有j个比它小的元素                //所以只要找右端中的第k-j小的元素就可以                return randomizedSelect(a,i+1,r,k-j);        }                private static int random(int i,int j){            Random r=new Random();            return r.nextInt(j-i)+i;            }        private static int partition(int[] a,int p,int r){           int i,j;           i=p;           j=r;           if((a==null)||(a.length==0))               return -1;           while(i

 

转载于:https://www.cnblogs.com/yijiesuifeng/p/3788439.html

你可能感兴趣的文章
iOS:KVO的概述与使用
查看>>
CLI使用案例4:灵活配置CLI
查看>>
Oracle12C 单实例dataguard配置
查看>>
MySQL入门介绍
查看>>
记JIRA服务,数据迁移,安装配置
查看>>
Linux下面监控系统性能的工具-vmstat
查看>>
Java Collection集合方法
查看>>
MySQL备份与恢复
查看>>
Linux---管理网络
查看>>
Can't load '/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/auto/DBD/mysql/mysql.so&#
查看>>
Ubuntu下nagios安装pnp4nagios插件
查看>>
PMP考试心得
查看>>
mariadb 实用功能3 修改表结构显示进度
查看>>
HSRP/VRRP网关冗余协议
查看>>
2.3 salt 初始化系统
查看>>
python2.7 MySQLdb insert
查看>>
47.磁盘格式化
查看>>
ansible安装tomcat_msm
查看>>
PL/SQL笔记
查看>>
hadoop-2.7.4+hbase-1.3.1+zookeeper-3.4.9搭建分布式集群环境
查看>>