最大堆的顺序存储操作集

最大堆的顺序存储操作集

typedef struct hnode {
    
    
	int *data;
	int size;
	int maxsize;
}*heap;

最大堆的根结点比所有子树节点都大

空堆的建立


#define maxdata 1000
#define false 0
#define true 1
heap create(int N) {
    
    
	heap h = (heap)malloc(sizeof(struct hnode));
	h->data = (int *)malloc(N * sizeof(int));
	h->maxsize = N;
	h->size = 0;
	h->data[0] = maxdata;   /*定义哨兵大于所有堆中元素,插入从1开始插*/
	return h;
}

int isfull(heap h) {
    
    
	if (h->size == h->maxsize) return true;
	else return false;
}
int isempty(heap h) {
    
    
	if (h->size == 0) return true;
	else return false;
}

最大堆的插入

int insert(heap h, int x) {
    
          /*空缺的为最后结点处,插入值自下而上上滤至合适位置*/
	if (isfull(h)) {
    
     
		printf("堆已满\n"); 
		return 0;
	}
	else {
    
    
		int i = ++h->size;
		for (; h->data[i/2]<x; i /= 2)   h->data[i] = h->data[i / 2];   /*i/2极限情况下为0,必定大于x,直接插入i==1处*/
		/*将插入元素从h->size开始将x依次向上挪,直至小于父节点(i/2),将x插入最后的儿结点(i)*/
		h->data[i] = x;
	}
	return true;
}

最大堆的删除

删除根结点

int deletemax(heap h) {
    
         /*删除最大值根结点为空,取最后一个元素自上而下下滤填入*/
	if (isempty(h)) {
    
    
		printf("none\n");
		return false;
	}
	else {
    
    
		int max = h->data[1];
		int temp = h->data[h->size--];
		int parent, child;
		for (parent = 1; parent * 2 <= h->size; parent = child) {
    
         
		/*确定有左子树*/
			child = parent * 2;
			if (child != h->size && h->data[child] < h->data[child + 1]) child++;     
			/*确定有无右子树,有取左右子结点最大值*/
			else {
    
    
				if (h->data[child] > temp) h->data[parent] = h->data[child];   
				/*temp比儿结点小向下传递,儿结点补到父节点空出位置 parent=空出的child数字填入*/
				else break;
			}
		}
		h->data[parent] = temp;            
		return max;
	}
	
}

最大堆的建立

最大堆建立:先将h->size个数据输入到数组中,再调整成为堆,每次调整应从最小的子树开始,依次向上调整,每次调整后根结点为该子树的最大值 ,再将两两子树合并,因此每次只需要将根结点下滤,用两个子结点中比它大的元素替换掉,并将它下滤至合适位置

void PercDown(heap 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;
}

void BuildHeap(heap H)
{
    
     /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
  /* 这里假设所有H->Size个元素已经存在H->Data[]中 */

	int i;

	/* 从最后一个结点的父节点开始,到根结点1 */
	for (i = H->size / 2; i>0; i--)
		PercDown(H, i);
}

猜你喜欢

转载自blog.csdn.net/qq_40602655/article/details/106603124