数据结构-二叉堆
二叉堆的百度百科 http://baike.baidu.com/view/668854.htm
二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
一般二叉堆有三种基本操作,添加,删除,修改
添加元素
首先把要添加的元素加到数组的末尾,然后和它的父节点(位置为当前位置减去1再除以2取整(k-1)/2,比如第4个元素的父节点位置是1,第7个元素的父节点位置是3)比较,如果新元素比父节点元素大则交换这两个元素,然后再和新位置的父节点比较,直到它的父节点不再比它小,或者已经到达顶端,即第1的位置。
* 删除元素
删除元素的过程类似,只不过添加元素是“向上冒”,而删除元素是“向下沉”:删除位置1的元素,把最后一个元素移到最前面,然后和它的两个子节点比较,如果两个子节点中较小的节点小于该节点,就将它们交换,直到两个子节点都比此顶点大。
计算两个子节点的位置的公式:左子节点:2K+1、右子节点:2K+2(注:这里针对的是根节点为零的情况,若根为1,则左右分别为2K与2K+1。
比如顶点为0,那么它的左右子节点分别为1和2位置,如果顶点为1,那么 1的左右两个子节点即为3,4.以此类推
* 修改元素
和添加元素完全一样的“向上冒”过程,只是要注意被修改的元素在二叉堆中的位置。
下面给出添加和删除的代码
假设一个原始堆为 1 2 3 4 5 6 7 8 9 10 11。。然后进行各种添加和删除的操作
#include <iostream> #include <stdio.h> #define minn(a,b) a>b?b:a #define exchange(a,b) { a=a+b;b=a-b;a=a-b;} int a[100];//a是一个最小堆 void insert(int i){ if(i==0) return; int fa=(i-1)/2; if(a[i]<a[fa]){ exchange(a[i],a[fa]); insert(fa); } return ; } void delect(int k){ int lc,rc; int n; lc=2*k+1; rc=2*k+2; if(!a[lc] && !a[rc]) return; if(!a[rc] && a[k]<=a[lc]) return; if(!a[rc] && a[k]>a[lc]){ exchange(a[k],a[lc]); return; } if(a[k]<a[lc] && a[k]<a[rc]) return; else{ n=a[lc]>a[rc]?rc:lc; exchange(a[k],a[n]); delect(n); return; } } int main() { int n; int i; int k; for(i=0;i<100;i++) a[i]=0; for(i=0;i<11;i++) a[i]=i+1; // insert n; scanf("%d",&n); for(i=0;i<100;i++) if(a[i]==0){ a[i]=n; break; } insert(i); //i表示数字n在哪个位子 //割******************************************* //delect n; /scanf("%d",&n);//输入要删除的数字,且这个堆里面。只出现一个n for(i=0;i<100;i++){ if(a[i]==n){ k=i; } if(a[i]==0) break; } i--; exchange(a[k],a[i]); a[i]=0; delect(k); //割********************************************* return 0; }