从无序数组中获取最小的M个元素(小顶堆实现)
2011-09-20 14:20
579 查看
我同学大龙给我出了一道算法题:给定一个长度为N无序的数组,怎么从中挑选出最小的M个数(M<=N)?
我的第一想法就是用快速排序将整个数组进行排序,然后遍历排序后的数组,从中选处M个最小的数。虽然这个方法可行,但是不是最好的。
用堆排序的思想就可以很好的解决这个问题。创建小顶堆,然后每次将堆顶最小元素抛出,循环M次即可获取最小的M个数。
这个算法题也可以认为是堆排序的一个应用。
堆排序算法请看我的另外一篇文章: http://www.cnblogs.com/mingmingruyuedlut/archive/2011/09/13/2175308.html
具体代码如下所示:
。。。。
我的第一想法就是用快速排序将整个数组进行排序,然后遍历排序后的数组,从中选处M个最小的数。虽然这个方法可行,但是不是最好的。
用堆排序的思想就可以很好的解决这个问题。创建小顶堆,然后每次将堆顶最小元素抛出,循环M次即可获取最小的M个数。
这个算法题也可以认为是堆排序的一个应用。
堆排序算法请看我的另外一篇文章: http://www.cnblogs.com/mingmingruyuedlut/archive/2011/09/13/2175308.html
具体代码如下所示:
/// <summary> /// 从给定的数组中获取N(count)个最小的数 /// </summary> /// <param name="array">传递的整形数组</param> /// <param name="count">获取count个最小的数</param> private static void GetSmallerNumbers(int[] array, int count) { BuildMinHeap(array); //创建小顶推 for (int i = array.Length - 1; i >= array.Length - count; i--) //遍历小顶推 { Console.WriteLine(array[0]); //输出最顶端的跟元素(即:此时堆中最小的数) Swap(ref array[0], ref array[i]); //将堆顶最小的元素与堆中最后的一个元素交换 MinHeapify(array, 0, i); //重新调整为小顶推 } } /// <summary> /// 创建小根堆 /// </summary> /// <param name="array">传递的数组</param> private static void BuildMinHeap(int[] array) { //根据堆与数组的关系可知:下标从 0 ~ array.Length / 2 - 1 的数组元素为根节点,其余元素都为叶节点 for (int i = array.Length / 2 - 1; i >= 0; i--) { MinHeapify(array, i, array.Length); //调整为小顶推 } } /// <summary> /// 从底向上:调整小根堆的过程 /// </summary> /// <param name="array">传递的数组</param> /// <param name="currentIndex">需要调整的当前根节点</param> /// <param name="heapSize">此时小顶堆的大小(即:处在小顶堆中所有的数组元素个数)</param> private static void MinHeapify(int[] array, int currentIndex, int heapSize) { int leftChildIndex = currentIndex * 2 + 1; //此根节点的左子节点下标 int rightChildIndex = currentIndex * 2 + 2; //此根节点的右子节点下标 int smallestIndex = currentIndex; //三者(根节点、左子节点、右子节点)之中最小元素的下标 if (leftChildIndex < heapSize && array[leftChildIndex] < array[smallestIndex]) { smallestIndex = leftChildIndex; } if (rightChildIndex < heapSize && array[rightChildIndex] < array[smallestIndex]) { smallestIndex = rightChildIndex; } if (smallestIndex != currentIndex) //左右子节点中存在小于根节点元素的情况 { Swap(ref array[currentIndex], ref array[smallestIndex]); MinHeapify(array, smallestIndex, array.Length); //递归调整 } } /// <summary> /// 交换函数 /// </summary> /// <param name="a">元素a</param> /// <param name="b">元素b</param> private static void Swap(ref int a, ref int b) { int temp = 0; temp = a; a = b; b = temp; }
。。。。
相关文章推荐
- 从无序数组中获取最小的M个元素(小顶堆实现)
- python实现获取序列中最小的几个元素
- Java/Go实现——把正整数数组的元素拼成一个最小的数
- php获取数组元素中头一个数组元素值的实现方法
- 黑马程序员——定义一个二维int数组,编写代码获取最小元素
- 剑指offer 01-06解答思路以及代码(顺序数组找特定数字,替换空格字符,链表反转输出,重建二叉树,两个栈实现队列效果,旋转数组最小元素)
- java编程:两个无序数组a和b,交换a,b中的元素,使得[序列a元素的和]与[序列b元素的和]之间的差最小。
- python实现获取序列中最小的几个元素
- 《数组-规划》 有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小
- 实现数组获取前K个最小数
- 用指针实现把数组的最小元素与第一个元素交换
- C#实现获取一个集合数组中出现次数最多的元素
- 【剑指Offer】旋转数组的最小元素——JavaScript实现
- C语言 选择排序算法原理和实现 从数组中 找出最小的元素然后交换位置
- C语言数组实现栈的基本操作,并利用O(1)求出栈中最小元素
- 定义一个二维int数组,编写代码获取最小元素
- PHP获取数组中重复最多的元素的实现方法
- 华为面试题 题目:有两个数组a,b,大小都为n,数组元素的值任意,无序; 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小
- 实现一个栈并获取其最小元素
- js实现从数组里随机获取元素