35 min_max_heap insert delete

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define MAXSIZE 100
#define FALSE 0
#define TRUE 1
#define MSWAP(x,y,temp) {temp=x;x=y;y=temp;}
///

//最小--最大堆   min_max_heap 
  //  insert  and  delete min
//
typedef struct
{
	int key;
}element;
element heap[MAXSIZE];


int level(int x)
{
	//如果为最小层  返回 0 FALSE
	//else  return  1;
	int t= ((int)(log((double)x) / log(2.0)))%2;
	if (t == 0) return FALSE;
	return TRUE;
}
void verify_min(element *heap, int i, element item)
{//将item填入以i为叶子的最小堆中
	//从i开始 依次 向上寻找节点 将item放入最小堆中合适的地方
	int grandparent = i / 4;
	while (grandparent)
	{
		if (item.key < heap[grandparent].key)
		{
			heap[i] = heap[grandparent];
			i = grandparent;
			grandparent /= 4;
		}
		else break;
	}
	heap[i] = item;
}


void verify_max(element *heap, int i, element item)
{//使item填入 以i为叶子的 最大堆中
	//从i开始 依次向上寻找节点  尽量将item放入更高的地方 
	int grandparent = i / 4;
	while (grandparent)
	{
		if (item.key > heap[grandparent].key)
		{
			heap[i] = heap[grandparent];
			i = grandparent;
			grandparent /= 4;
		}
		else
			break;
	}
	heap[i] = item;
}

void min_max_insert(element *heap, int *n, element item)
{

	/*insert an item*/
	int parent;
	(*n)++;
	if (*n == MAXSIZE) { exit(1); }

	parent = (*n) / 2;

	if (!parent) heap[1] = item; // 插入后只有一个元素 玩个毛线  插就行了
	else
	{
		switch (level(parent))//对父亲节点 所在层进行判断
		{
		case FALSE://父亲节点位于最小层,新插入元素在最大层
			if (item.key < heap[parent].key)//新插入的元素 是 最大支链中的最小值 则 只需处理 在 最小支链中的位置
			{
				heap[*n] = heap[parent];
				verify_min(heap, parent, item);//将item插入到
			}
			else
			{
				verify_max(heap, *n, item);
			}
			break;
		case TRUE://父亲结点位于最大层,新插入元素位于最小层
			if (item.key >heap[parent].key)
			{
				heap[*n] = heap[parent];
				verify_max(heap, parent, item);
			}
			else
			{
				verify_min(heap, *n, item);
			}
			break;
		}
	}



}
int min_child_grandchild(int i, int *n, element *heap)
{
	int min,t;
	if (2 * i > *n) { printf("error !"); exit(1); }
	min = 2 * i;
	if (2*i+1<*n && heap[2 * i + 1].key < heap[min].key) min = 2 * i + 1;
	for (t = 0+4*i; t < *n && t<4*i + 4; t++)
	{
		if (heap[t].key < heap[min].key) min = t;
	}
	return min;
}


element delete_min(element heap[], int *n)
{
	int i, last, k, parent;
	element temp, x;

	if (!(*n))
	{
		exit(0);
	}
	heap[0] = heap[1]; //save the element to return 

	x = heap[(*n)--];
	/* find place to insert */
	for (i = 1, last = (*n) / 2; i <= last;)
	{
		k = min_child_grandchild(i, n,heap);//用来确定i节点的所有儿子和后代结点中的 关键字值 最小 的结点

		if (x.key <= heap[k].key)break;//找到位置
		/*case 2--b or 2---c*/
		heap[i] = heap[k];
		if (k <= 2 * i + 1)
		{
			i = k; break;
		}
		2--c
		parent = k / 2;
		if (x.key > heap[parent].key)
			MSWAP(heap[parent], x,temp);//swap(heap[parent],x);
		;
		i = k;
	}

	heap[i] = x;
	return heap[0];

}
//by zhaoyang 2014.5.7
void output(element *heap,int num)
{
	for (int i = 1; i <= num; i++)
		printf("%d  ", heap[i]);
	printf("\n");
}

int main()
{
	element tmp[100],temp;
	int num = 0;
	for (int i = 0; i < 10 ;i++)	
	{
		temp.key = i;
		min_max_insert(tmp, &num, temp);
		output(tmp, num);
	}
	return 0;

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值