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


    一、直接排序找中位数

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

  • 相关阅读:
    伪造mysql服务端实现任意读取
    客户端session安全问题(flask)
    systemd教程
    MySQL的一些常用基本命令的使用说明
    AMD、CMD、CommonJs和ES6的区别
    for in与for of的区别,以及forEach,map,some,every,filter的区别
    EcmaScript 6 十大常用特性
    单行省略号与多行省略号
    Array.prototype.slice.call()详解及转换数组的方法
    返回顶部
  • 原文地址:https://www.cnblogs.com/MrLiuZF/p/15171854.html
Copyright © 2020-2023  润新知