如何在N个无序数组元素中,查找第K大元素

来源:互联网 发布:超图软件 新浪财经 编辑:程序博客网 时间:2024/04/30 01:19

这个问题的解决肯定是要先排序的,然后再定位,区别在于 查找第K大元素 不需要将整个数组全部排序,找到第K大元素即可停下。可以用冒泡沉底法之类的排序方法,本例中使用的是我上一篇文章中介绍的堆排序算法,在这个算法的基础上改动一行代码就可以实现了,即将for(int i = array.length - 1; i >= 2; i--)循环的结束条件修改为for(int i = array.length - 1; i >= array.length - (k + 1); i--)。请看下面代码:

<span style="font-size:14px;">package com.lee.sort;public class HeapSort {    /**     * 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。     * 堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。     * 堆排序的平均时间复杂度为Ο(nlogn) 。     * 算法步骤:     * 1. 创建一个堆H[0..n-1]     * 2. 把堆首(最大值)和堆尾互换     * 3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置     * 4. 重复步骤2,直到堆的尺寸为1     *     *     *     *注意:本例中元素序号从1开始。。。     * @param args     */            private static int heap_size = 0;   //最大堆的长度        private static int k = 4;    public static void main(String[] args) {        // TODO Auto-generated method stub        int[] array = {0, 8, 20, 15, 11, 50, 30, 90, 77, 33, 56};        System.out.println("排序前..........................");        for(int i = 1; i < array.length; i++){            System.out.print(array[i] + "   ");        }        System.out.println();                heap_size = array.length;        heapSort(array);                System.out.println("排序后.........................");        for(int i = 1; i < array.length; i++){            System.out.print(array[i] + "   ");        }    }        private static void heapSort(int[] array){        if(array == null || array.length <= 1){            return;        }        buildHeap(array);<span style="color:#FF0000;">        //for(int i = array.length - 1; i >= 2; i--){   //        /** 寻找第k大元素,假设k = 4,因为本例中数组其实位置1,所以array.length - (k + 1),也可以这样理解:        *   i = array.length - 1找到的是最大值,i = array.length - 1 - k则是第K大的值        *           *   */        for(int i = array.length - 1; i >= array.length - (k + 1); i--){  </span>            swap(array, i, 1);            heap_size--;            maxHeapValue(array, 1);            if(i == array.length - k - 1){                System.out.println("第K大元素值: " + array[array.length - k - 1]);            }        }    }        /**     * 交换数组元素的值     *      * */    private static void swap(int[] array, int i, int j){        int temp = 0;        temp = array[i];        array[i] = array[j];        array[j] = temp;    }    //构建最大堆    private static void buildHeap(int[] array){                for(int i = array.length/2; i >= 1; i--){        //for(int i = 1; i < array.length/2 + 1; i++){            maxHeapValue(array, i);        }    }         /**     * 构建最大堆时,查找最大值     *      * 假设array[i]是最大值,即假设i是最大值的索引     * */    private static void maxHeapValue(int[] array, int i){        int left = 2 * i;   //最大堆左子树的索引值        int right = 2 * i + 1;  //最大堆右子树的索引值        int max = 0;    //记录最大值的索引值                //判断左子树是否存在,且比较,找出更大值的索引        if(left < heap_size && array[left] > array[i]){            max = left;        } else {            max = i;        }                //判断右子树是否存在,且比较,找出更大值的索引        if(right < heap_size && array[right] > array[max]){            max = right;        }                System.out.println("------- max == " + max + ", i = " + i);                if(max == i){                        return;        } else {            swap(array, max, i);                        for(int a = 1; a < array.length; a++){                System.out.print(array[a] + "   ");            }            System.out.println();            //交换之后调整子树,保持最大堆性质            maxHeapValue(array, max);        }    }}</span>

运行过程与结果:

排序前..........................
8   20   15   11   50   30   90   77   33   56   
------- max == 10, i = 5
8   20   15   11   56   30   90   77   33   50   
------- max == 10, i = 10
------- max == 8, i = 4
8   20   15   77   56   30   90   11   33   50   
------- max == 8, i = 8
------- max == 7, i = 3
8   20   90   77   56   30   15   11   33   50   
------- max == 7, i = 7
------- max == 4, i = 2
8   77   90   20   56   30   15   11   33   50   
------- max == 9, i = 4
8   77   90   33   56   30   15   11   20   50   
------- max == 9, i = 9
------- max == 3, i = 1
90   77   8   33   56   30   15   11   20   50   
------- max == 6, i = 3
90   77   30   33   56   8   15   11   20   50   
------- max == 6, i = 6
------- max == 2, i = 1
77   50   30   33   56   8   15   11   20   90   
------- max == 5, i = 2
77   56   30   33   50   8   15   11   20   90   
------- max == 5, i = 5
------- max == 2, i = 1
56   20   30   33   50   8   15   11   77   90   
------- max == 5, i = 2
56   50   30   33   20   8   15   11   77   90   
------- max == 5, i = 5
------- max == 2, i = 1
50   11   30   33   20   8   15   56   77   90   
------- max == 4, i = 2
50   33   30   11   20   8   15   56   77   90   
------- max == 4, i = 4
------- max == 2, i = 1
33   15   30   11   20   8   50   56   77   90   
------- max == 5, i = 2
33   20   30   11   15   8   50   56   77   90   
------- max == 5, i = 5
------- max == 3, i = 1
30   20   8   11   15   33   50   56   77   90   
------- max == 3, i = 3
第K大元素值: 33
排序后.........................
30   20   8   11   15   33   50   56   77   90  
 

0 0