欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一种二叉堆实现

程序员文章站 2022-06-06 20:56:11
...

二叉堆结构性质:是一颗完全二叉树

二叉堆堆序性质:最小元在根上,而且左右子树也一个二叉堆

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

#define ElementType int

struct binary_heap {
	int capacity;
	int size;
	ElementType *Elements;
};

struct binary_heap *H;

int init_binary_heap(int size)
{
	if(NULL == H)
	{
		H = malloc(sizeof(struct binary_heap));
		if(NULL == H)
		{
			printf("Error: out of memory!!\n");
			return -1;
		}
		H->Elements = malloc(sizeof(ElementType)*(size + 1));
		if(NULL == H->Elements)
		{
			printf("Error: out of memory!!\n");
			return -1;
		}
		H->capacity = size;
		H->size = 0;
		H->Elements[0] = -1;//标记
	}
	return 0;
}

int insert_binary_heap(ElementType e)
{
	int i;
	if(H->size + 1 > H->capacity)
	{
		printf("Error: the binary heap is already full!!\n");
		return -1;
	}
	for(i = ++H->size;H->Elements[i] = e,H->Elements[i] < H->Elements[i/2];i = i/2)
	{	
		H->Elements[i] = H->Elements[i/2];
	}
	H->Elements[i] = e;
	return 0;
}

ElementType delete_min_binary_heap(void)
{
	ElementType result;
	int i;
	if(H->size == 0)
	{
		printf("Error: the binary heap is already empty!!\n");
		return -1;
	}
	//先获得二叉堆的根
	result = H->Elements[1];
	H->Elements[1] = H->Elements[H->size];
	//如果存在左分支,且根的值大于左分支的值,则进行下虑
	i = 1;
	while(2*i <= H->size)
	{
		//判断是否同时有左右分支
		if(2*i + 1 <= H->size)
		{
			//根大于左,根大于右
			if(H->Elements[i] > H->Elements[2*i] && H->Elements[i] > H->Elements[2*i+1])
			{
				if( H->Elements[2*i] < H->Elements[2*i+1])
				{
					H->Elements[i] = H->Elements[2*i];
					H->Elements[2*i] = H->Elements[H->size];
					i = 2*i;
				}
				else
				{
					H->Elements[i] = H->Elements[2*i+1];
					H->Elements[2*i+1] = H->Elements[H->size];
					i = 2*i+1;
				}
			}
			//根大于左,根小于右
			else if(H->Elements[i] > H->Elements[2*i] && H->Elements[i] < H->Elements[2*i+1])
			{
				 H->Elements[i] = H->Elements[2*i];
				 H->Elements[2*i] = H->Elements[H->size];
				 i = 2*i;
			}
			//根小于左,根大于右
			else if(H->Elements[i] < H->Elements[2*i] && H->Elements[i] > H->Elements[2*i+1])
			{
				H->Elements[i] = H->Elements[2*i+1];
				H->Elements[2*i+1] = H->Elements[H->size];
				i = 2*i+1;
			}
			else
			{
				break;
			}
		}
		//只有左分支
		else
		{
			if(H->Elements[i] > H->Elements[2*i])
			{
				H->Elements[i] = H->Elements[2*i];
				H->Elements[2*i] = H->Elements[H->size];
				i = 2*i;
			}
			else
			{
				break;
			}
		}
	}

	H->Elements[H->size] = 0;//将最后一个清零
	H->size--;
	return result;
}

void print_binary_heap(void)
{
	int i;
	printf("the current binary heap: ");
	for(i = 0;i < H->capacity + 1;i++)
		printf("%d ",H->Elements[i]);
	printf("\n");
	return;
}

int main(void)
{
	ElementType e;
	init_binary_heap(10);
	scanf("%d",&e);
	while(e != 0)
	{
		insert_binary_heap(e);
		scanf("%d",&e);
	}
	print_binary_heap();
	//delete操作
	while(H->size != 0)
	{
		e = delete_min_binary_heap();
		printf("get the min value from the curret binary heap is %d\n",e);
	}

	return 0;
}

运行结果:

一种二叉堆实现