堆实际上指的就是优先队列的一种数据结构,它的第1个元素有最高的优先权,用malloc函数分配内存时就放在堆上,这块内存不会自动释放,用new申请,用delete删除。
堆的空间分存不一定连续,随申请的内存块大小的不同放置在不同地址,但遵循“从低地址向高地址扩展”的原则。一般在堆的头部用一个字节表示堆的大小,
堆是一个完全(除最底层外都是满的)二叉树,并满足如下条件:
1、根结点若有子树,则子树一定也是堆。
2、根结点一定大于(或小于)子结点。
二叉堆通常用数组来实现,它舍弃下标0,从下标1开始置数.对于数组中任意位置i上的元素,其左儿子的位置在2i上,右儿子的位置在2i+1上,双亲的位置则在i/2上。
堆排序算法:应用最大堆,是一种效率为O(nlgn)的原地排序算法。
堆排序的算法之一是把数组构建成二叉堆----这只要增添一个长度为n+1的辅助空间,然后把原数组的元素依次插入到二叉堆即可。然后删除二叉堆的根,把它作为排序后的数组的第一个元素,然后使二叉堆的长度减1,并通过上移使得新得到的序列仍为二叉堆,再提取新二叉堆的第一个元素到新数组。依此类推,直到提取最后一个元素,新得到的数组就是排序后的数组。
最小堆(min Heap)他的每个节点的值都小于其孩子的值,最大堆相反
pop_heap();
它的函数原型是:void pop_heap(first_pointer,end_pointer,compare_function);
作用:pop_heap()不是真的把最大(最小)的元素从堆中弹出来,而是重新排序堆。它
把first和last交换,然后将[first,last-1)的数据再做成一个堆。
push_heap()
void pushheap(first_pointer,end_pointer,compare_function);
作用:push_heap()假设由[first,last-1)是一个有效的堆,然后,再把堆中的新元素加进来(新加入的元素为last),做成一个堆。
sort_heap()
void sort_heap(first_pointer,end_pointer,compare_function);
作用是sort_heap对[first,last)中的序列进行排序。它假设这个序列是有效堆。(当然,经过排序之后就不是一个有效堆了)
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
http://blog.csdn.net/aipb2008/archive/2008/03/29/2227516.aspx
http://tech.ddvip.com/2009-05/1243333102121230.html
http://blog.chinaunix.net/u2/76292/showart_1993970.html
1.INSERT
思路是基于一种“上滤”的策略,设堆为H,待插入的元素为X,首先在size+1的位置建立一个空穴,然后比较X和空穴的爸爸的大小,把“大的爸爸”换下来,以此推进,最后把X放到合适的位置。
2.DELETEMIN
与上面的上滤对应,这将是一种“下滤”的策略,就是逐层推进,把较小的孩子换上来,这里面有个小的问题在具体算法实现上要注意,设堆的最后一个元素是L,在推进到倒数第二层时,将导致最后一层的某个孩子被换上去而产生一个洞,这时候为了保持堆的结构,必须把最后一个元素运过去补上,此时就存在一个问题,如果L比那个孩子小的话就不能保证堆序的性质了,所以在程序中要加一个if语句来进行这个边界条件的处理,还是那句话,对于一个完整的程序,算法是重要的一方面,而对算法边界问题的处理则是更重要的一方面。
#include <stdio.h> |