Java求无序数组中位数,无序数组的中位数(PriorityQueue小顶堆解法)(Java)

思路:

1、快排思想

2、小顶堆或者大顶堆(使用优先级队列PriorityQueue实现小顶堆)

3、top k问题可采用类似解法。

代码:

package com.my.test.datastructure.array;

import java.util.Comparator;

import java.util.PriorityQueue;

/**

* 无序数组的中位数

*

* 获取排序后的第size/2(size为偶数),(size+1)/2(size为奇数)个元素

* 对应下标为(size-1)/2

*

*/

public class ArrMidNum

{

/**

* 快排思想-直至mid为(size-1)/2

*

*/

public static int getMidNum(int[] arr) {

if (arr == null || arr.length <= 0) {

return -1;

}

int size = arr.length;

int targetMid = (size-1)/2;

int low = 0;

int high = size - 1;

int mid = getMid(arr, low, high);

while (mid != targetMid) {

if (mid < targetMid) {

mid = getMid(arr, mid + 1, high);

} else {

mid = getMid(arr, low, mid - 1);

}

}

return arr[mid];

}

/**

* 快排思想-一趟排序

*/

private static int getMid(int[] arr, int low, int high) {

int base = arr[low];

while (low < high) {

// 判断条件必须加=场景,为<= 不能为

while (low < high && base <= arr[high]) {

high--;

}

arr[low] = arr[high];

// 判断条件必须加=场景,为>= 不能为>,否则数组中有相同数据时,会一直循环

while (low < high && base >= arr[low]) {

low++;

}

arr[high] = arr[low];

}

arr[low] = base;

return low;

}

/**

* 堆排序,组建一个(size+1)/2大小的最小堆 ,取到top (size+1)/2个大的值,则堆顶元素即为中位数

*

* 先取前(size+1)/2个元素,组成最小堆,剩下的元素和堆顶比较,比堆顶小则忽略,比堆顶大则交换,然后重组最小堆

*/

public static int getMidNumByMinHeap(int[] arr) {

if (arr == null || arr.length <= 0) {

return -1;

}

// 内部实现了最小堆(默认自然序)

PriorityQueue queue = new PriorityQueue<>();

// 初步组建最小堆

int size = arr.length;

int heapSize = (size + 1) / 2;

for (int i=0; i

queue.offer(arr[i]);

}

// 比较余下元素,比堆顶大则替换堆顶元素为新值

for (int j=heapSize;j

int temp = arr[j];

// 当前元素比堆顶大 则删除堆顶元素,把当前元素加入堆

if (queue.peek() < temp) {

queue.poll();

queue.offer(temp);

}

}

// 返回堆顶元素

return queue.peek();

}

/**

* 堆排序,组建一个(size+1)/2大小的最大堆 ,取到top (size+1)/2个小的值,则堆顶元素即为中位数

*

* 先取前(size+1)/2个元素,组成最大堆,剩下的元素和堆顶比较,比堆顶大则忽略,比堆顶小则交换,然后重组最大堆

*/

public static int getMidNumByMaxHeap(int[] arr) {

if (arr == null || arr.length <= 0) {

return -1;

}

// 内部实现了最大堆(实现自定义从大到小排序)

PriorityQueue queue = new PriorityQueue<>(new Comparator() {

@Override

public int compare(Integer o1, Integer o2)

{

return o2 - o1;

}

});

// 初步组建最大堆

int size = arr.length;

int heapSize = (size + 1) / 2;

for (int i=0; i

queue.offer(arr[i]);

}

// 比较余下元素,比堆顶小则替换堆顶元素为新值

for (int j=heapSize;j

int temp = arr[j];

// 当前元素比堆顶大 则删除堆顶元素,把当前元素加入堆

if (queue.peek() > temp) {

queue.poll();

queue.offer(temp);

}

}

// 返回堆顶元素

return queue.peek();

}

public static void main(String[] args)

{

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

System.out.println(getMidNum(arr));

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

System.out.println(getMidNumByMinHeap(arr1));

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

System.out.println(getMidNumByMaxHeap(arr2));

}

}

参考:

标签:arr,Java,int,PriorityQueue,low,小顶,public,size

来源: https://blog.csdn.net/zangdaiyang1991/article/details/88641830

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值