1. 程式人生 > 其它 >找出無序陣列中位數的方法

找出無序陣列中位數的方法

一、直接排序找中位數

  直接利用自帶的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

本文來自部落格園,作者:Mr-xxx,轉載請註明原文連結:https://www.cnblogs.com/MrLiuZF/p/15171854.html