#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;
}
35 min_max_heap insert delete
最新推荐文章于 2021-02-19 00:34:18 发布