最小堆的基本操作集

最小堆的基本操作集

1、准备工作,创建堆的结构体

#define MINDATA -100000
struct node{
	int* data;    //指向数组,储存堆中的元素 
	int size;     //堆的当前大小 
	int capacity; //堆的容量 
}; 
typedef struct node* MinHeap;

2、初始化最小堆

MinHeap CreateHeap(int maxsize){  
	MinHeap H=(MinHeap)malloc(sizeof(struct node));
	H->data=(int*)malloc(sizeof(int)*(maxsize+1));
	H->size=0;
	H->capacity=maxsize;
	H->data[0]=MINDATA;    //在数组的0位置上放置哨兵  
	return H; 
}

3、检测堆是否已满

bool IsFull(MinHeap H){
	return (H->size==H->capacity);
}

4、向最小堆中插入元素

bool Insert(MinHeap H,int x){
	if(IsFull(H)) return false;
	int i=H->size+1;
	H->size++;            //将新元素放置在数组的最后一位 
	for(;H->data[i/2]>x;i/=2){
		H->data[i]=H->data[i/2];  //若当前的父节点大于插入元素,则将插入元素向上滤 
	} 
	H->data[i]=x;  //将插入元素放到正确的位置 
	return true;
}

5、从最小堆中弹出元素

int DeleteMax( MinHeap H ) /* 从最小堆H中取出键值最小的元素,并删除一个结点 */
{ 
    int Parent, Child;
    int MinItem, X;
 
    if ( IsEmpty(H) ) {
        printf("最小堆已为空");
        return ERROR;
    }
 
    MinItem = H->Data[1]; /* 取出根结点存放的最小值 */
    /* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */
    X = H->Data[H->Size--]; /* 注意当前堆的规模要减小 */
    for( Parent=1; Parent*2<=H->Size; Parent=Child ) {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]>H->Data[Child+1]) )
            Child++;  /* Child指向左右子结点的较小者 */
        if( X <= H->Data[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = X;
    
    return MinItem;
}

6、更快的建堆方式
不需要循环插入,而是先构造一棵完全二叉树,再对其进行调整,使其所有子树均为最小堆

 void BuildHeap( MinHeap H ){
/* 调整H->Data[]中的元素,使满足最小堆的有序性  */
/* 这里假设所有H->Size个元素已经存在H->Data[]中 */
    int i;
    for( i = H->Size/2; i>0; i-- ) /* 从最后一个结点的父节点开始,到根结点1 */
        PercDown( H, i );
}

void PercDown( MinHeap H, int p )
{ /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
    int Parent, Child;
    int X;
    X = H->Data[p]; /* 取出根结点存放的值 */
    for( Parent=p; Parent*2<=H->Size; Parent=Child ) {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]>H->Data[Child+1]) )
            Child++;  /* Child指向左右子结点的较小者 */
        if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = X;
}

你可能感兴趣的:(板子库)