java 线性时间选择_分治法-线性时间选择

算法思想:分治法

实际问题:线性时间选择

编写语言:Java

问题描述

给定线性序集中 n 个元素和一个整数 k, 1 <= k <= n, 要求找出这 n 个元素中第 k 小的元素。即如果将这 n 个元素依其线性序排列时,排在第 k 个位置的元素即为要找的元素。

本篇博文代码会用到 分治法-快速排序 博文中用到的基准选择方法。

方法使用位置:代码第 25 行

方法实现位置:代码第 37 - 68 行

Java代码

import java.util.Random;

public class RandomizedSelect

{

public static void main(String[] args)

{

int[] a = new int[] {1, 3, 2, 6, 5, 8, 4, 9, 7, 0};

int t = select(a, 0, a.length - 1, 4); //选出第四大的数

System.out.println(t);

}

//参数含义:a为待查询的数组,low为起点,high为终点,target为带查询的目标

public static int select(int[] a, int low, int high, int target)

{

if(low == high)

return a[low];

//将数组以i为基准分为两部分,左边的都小于i,右边的都大于i

//此处会用到快速排序算法中的划分方法来找基准

int i = randPart(a, low, high);

int length = i - low + 1; //数组左半部分的长度

//如果第target小的数小于等于左半部分的长度,则这个数在此部分内

if(target <= length)

return select(a, low, i, target);

//如果第target小的数大于左半部分的长度,则这个数在右半部分内,

//且左半部分的数都小于第target小的数

else

return select(a, i + 1, high, target - length);

}

//划分寻找基准-随机化优化

public static int randPart(int[] a, int low, int high)

{

Random r = new Random();

//随机产生一个 low 到 high 的整数

int flag = low + r.nextInt(high - low + 1);

int pivot = a[flag];

//实际还是相当于以a[0]为基准

a[flag] = a[low];

a[low] = pivot;

while(low < high)

{

//1、从右往左找比基准小的数

while(low < high && a[high] > pivot)

high--;

if(low < high)

a[low] = a[high];

//2、从左往右找比基准大的数

while(low < high && a[low] <= pivot)

low++;

if(low < high)

a[high] = a[low];

}

//将pivot放到low和high相遇的地方

a[high] = pivot;

return high;

}

}

运行结果

d7c788e4a472412244d339e58b942306.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值