找出无序数组中位数的方法

一、直接排序找中位数

  直接利用自带的sort方法排序,然后返回数组的中间索引的值
代码如下:

1     //1.直接排序
2     public static int findMediaMethod1(int[] a)
3     {
4         if(a.length==0) return -1;
5         Arrays.sort(a);
6         return a[(a.length-1)/2];
7     }

 

  第一种方法太暴力了,我们只需要中位数即可,而不需要对数组中所有的元素进行处理。这就引申出了第二种方法。

二、利用快排思想

  快排的基本思想是选取一个哨兵元素,然后设立两个指针left,right,分别指向左端和右端,两个指针相向运动,当左右指针都遇到了违反数组次序的元素的时候左右指针交换元素(违反数组次序是指左指针找到了大于哨兵元素的元素或右指针找到了小于哨兵元素的值),这样当左右指针相遇的时候,左边的数组元素一定小于等于哨兵元素,右边的数组元素一定大于等于哨兵元素。我们可以利用这一性质来找中位数,每次进行快排操作后记录下哨兵元素的位置,如果大于中间元素的话,则我们只需要对左边进行快排操作,当小于中间元素,我们只需要对右边进行快排操作,跟二分查找很像。
  代码如下:

 1     //2.利用快排原理进行排序
 2     public static int findMediaMethod2(int[] a)
 3     {
 4         if(a.length==0) return -1;
 5         //中位数位置
 6         int mid=(a.length-1)/2;
 7         //左右指针位置
 8         int left=0,right=a.length-1;
 9         //进行快排操作后哨兵元素的位置
10         int qsIdx=0;
11         qsIdx = quickSort(left,right,a);
12         while(true)
13         {
14             //System.out.println("qsIdx= "+qsIdx);
15             if(qsIdx==mid)
16             {
17                 break;
18             }
19             else if(qsIdx<mid) qsIdx=quickSort(qsIdx+1,right,a);
20             else qsIdx=quickSort(left,qsIdx-1,a);
21         }
22         return a[qsIdx];
23     }
24     public static int quickSort(int left,int right,int[] a)
25     {
26         int target=a[left];
27         while(left<right)
28         {
29             while(left<right&&a[right]>=target) right--;
30             a[left]=a[right];
31             while(left<right&&a[left]<=target) left++;
32             a[right]=a[left];
33         }
34         //System.out.println("left="+left);
35         a[left]=target;
36         return left;
37     }

三、利用大小堆性质

  大顶堆存数组中较小部分的元素,小顶堆存数组中较大部分的元素,相当于将数组分成两半了,这样大顶堆的堆顶或小顶堆的堆顶就是我们找的中位数。

  如何实现呢?
    1. 当插入堆中的元素个数为偶数时,将当前元素插入大顶堆,将大顶堆的堆顶元素插入小顶堆
    2. 当插入堆中的元素个数为奇数时,将当前元素插入小顶堆,将小顶堆的堆顶元素插入大顶堆
  代码如下:

 1  //3.利用大顶堆和小顶堆性质进行排序
 2     public static int findMediaMethod3(int[] a)
 3     {
 4         if(a.length==0) return -1;
 5         Queue<Integer> minHeap = new PriorityQueue<Integer>();
 6         Queue<Integer> maxHeap = new PriorityQueue<Integer>(new Comparator<Integer>() {
 7             @Override
 8             public int compare(Integer o1, Integer o2) {
 9                 return o2-o1;
10             }
11         });
12         for (int i=0;i<a.length;i++)
13         {
14             if(i%2==0)
15             {
16                 maxHeap.add(a[i]);
17                 int top = maxHeap.poll();
18                 minHeap.add(top);
19             }
20             else
21             {
22                 minHeap.add(a[i]);
23                 int top = minHeap.poll();
24                 maxHeap.add(top);
25             }
26         }
27         return a.length%2==0? maxHeap.peek():minHeap.peek();
28     }

四、转载于

https://blog.csdn.net/qq_41410799/article/details/103956037

posted @ 2021-08-22 11:59  Mr-xxx  阅读(869)  评论(0编辑  收藏  举报