存在大量数据时,需要求前k个最大或最小的数据,当数据量太大时,排序有可能会出错(数据量太大以至于不能直接加载入内存中),此时可以应用堆来解决。 步骤: 1、取前k个数据建堆; 2、依次读取随后数据,将满足要求的进堆; 3、读取完所有数据,堆中即为前k个所需的数据。 问题:当需要前k个最大的数据时,建小...
* 1.结构性:堆必须是一颗完全二叉树 * 2.堆序性:堆的父节点要么都大于子节点,要么小于子节点,前者叫大顶堆,后者叫小顶堆; * 由此,堆可以用一个数组来表示,并有如下性质: * 1.对于任意i位置的元素,他的左子节点在2i位置,右子节点在2i+1位置(前提是根节点下标从1开始,如果从0开始则是<2i+1,2i+...
我们都知道二叉树是度为2的树,如果在一个完全二叉树里,所有的子结点都小于他的父结点,那么它就是堆。这样的堆被称之为大堆,反之则称为小堆。 虽然我们画出它的模型是完全二叉树的样子,但实际上堆的数据是存放在一个一维数组里的,不用惊慌,如下三个公式便可以解决我们于堆访问的问题。归根结底还是数学问题。
由于在插入新元素之前,这个堆本身是有序的(也就是对每个节点来说,都有根节点 > 左右子节点)。 那么,我们就可以在堆末尾插入新的元素,这样只需要比较新插入的元素和他的根节点,然后交换位置,直到找到合适的位置,这样就完成了插入新元素的操作。(这个操作,我们称之为自底向上堆化) 如下: void AddToHeap(Heap *...
堆的实现 为了实现一个堆,我们需要创造一个堆的数据结构,以及实现堆的插入和删除等操作函数。 堆的存储 由于堆是完全二叉树,因此可以用数组存放堆。第i个节点就放在数组的第i个位置上。它的左子节点是 2i, 它的右子节点是2i+1, 它的父节点是i/2. ...
3 堆栈的第一个操作,Push。向堆栈顶部放置一个数据。我们在实现时也比较简单,将数据添加到堆栈数组中top位置处,并使top加1,指向下一个位置。 4 Push操作时,其实还有一个步骤,当堆栈已满的情况下,我们需要动态的重新申请内存,扩展堆栈容量。如果省略了这一步骤,那么和普通的数组一样就缺少了灵活性了。
步骤2:构建最大堆通过堆化操作将二叉树转换为最大堆。 步骤3:通过将最大元素放到未排序数组末尾来排序数组不断重复上述步骤,直到堆中只剩下一个元素。 堆排序的实现 #include <stdio.h> // 堆化以节点 i 为根的子树 void heapify(int arr[], int n, int i) { ...
堆排序(升序)代码 /** (最大)堆的向下调整算法** 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。* 其中,N为数组下标索引值,如数组中第1个数对应的N为0。** 参数说明:* a -- 待排序的数组* start -- 被下调节点的起始位置(一般为0,表示从第1个开始)* end ...
C语言堆串的简单实现 1、String.h #ifndef __STRING_H__ #define __STRING_H__ #define MAXLEN255#define CHUNKSIZE4//串多采用顺序存储结构typedef struct{char ch[MAXLEN+1];int length;}SString;//串的定长顺序存储结构typedef struct{char*ch;int length;}HString;//串的堆式顺序存储结构typedef ...
建堆操作则利用向下调整的方法对堆数组的每一个元素进行向下调整,从而使得每一个节点都是以其为根结点的树中的最小元素。而通过二叉树我们可以知道,叶子节点是没有孩子的,因此对于叶子节点可以不用再进行向下调整,因此第一个调整的节点则是最后一个元素的父节点,因为它是树中最后一个还拥有孩子的节点。实现代码如...