您的位置:首页 > 理论基础 > 数据结构算法

数据结构之优先队列(二叉堆)

2014-12-23 20:22 447 查看
简单的实现了一下二叉堆的创建,初始化,以及取最大,最小元素(大根堆,小根堆)。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define father(i) ((i) >> 1)  // 父节点
#define lchild(i) ((i) << 1) // 左结点
#define rchild(i) (((i) << 1) +1 ) // 右结点
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)>(b)?(b):(a))
typedef int ElemType;
typedef struct HeapStruct
{
	int nSize;
	ElemType *nData;
}HeapStruct, *Heap;
void Swap(void *a, void *b)
{
	int temp = *(int *)a;
	*(int *)a = *(int *)b;
	*(int *)b = temp;
}
void InitializeHeap(Heap *pHeap,int Size)
{
	*pHeap = (Heap)malloc(sizeof(HeapStruct));
	(*pHeap)->nData = (int *)malloc((Size + 1) * sizeof(ElemType));
	memset((*pHeap)->nData, 0, (Size + 1) * sizeof(ElemType));
	(*pHeap)->nSize=0;
}
void DestoryHeap(Heap *pHeap)
{
	free((*pHeap)->nData);
	free(*pHeap);
	*pHeap = NULL;
}
// 创建小根堆
void Insert_Num_Use_Min(Heap pHeap, ElemType nData)
{
	int nPos = ++pHeap->nSize;
	for (; pHeap->nData[father(nPos)] > nData; nPos >>=1)
	{
		pHeap->nData[nPos]=pHeap->nData[father(nPos)];
	}
	pHeap->nData[nPos] = nData;
}
// 创建大根堆
void Insert_Num_Use_Max(Heap pHeap, ElemType nData)
{
	int nPos;
	pHeap->nData[nPos = ++pHeap->nSize] = nData;
	while (nPos > 1)
	{
		if (pHeap->nData[nPos] > pHeap->nData[nPos >> 1])
		{
			Swap(&pHeap->nData[nPos], &pHeap->nData[nPos >> 1]);
			nPos >>= 1;
		}
		else
			break;
	}
}
// 弹出大根堆中最大元素
ElemType PopMax(Heap pHeap)
{
	if (pHeap->nSize == 0)
		return;
	int i=1, nValue = pHeap->nData[1];
	pHeap->nData[1] = pHeap->nData[pHeap->nSize];
	while (1)
	{
		if (lchild(i) <= pHeap->nSize && rchild(i) <= pHeap->nSize)
		{
			if (pHeap->nData[i] > Max(pHeap->nData[lchild(i)], pHeap->nData[rchild(i)]))
				break;
			if (pHeap->nData[lchild(i)] > pHeap->nData[rchild(i)])
			{
				Swap(&pHeap->nData[i], &pHeap->nData[lchild(i)]);
				i  <<= 1;
			}
			else
			{
				Swap(&pHeap->nData[i], &pHeap->nData[rchild(i)]);
				i = ( i << 1) + 1;
			}
		}
		else
			break;
	}
	pHeap->nSize--;
	return nValue;
}
// 弹出小根堆中最小元素
ElemType PopMin(Heap pHeap)
{
	if (pHeap->nSize == 0)
		return;
	int i = 1, nValue = pHeap->nData[1];
	pHeap->nData[1] = pHeap->nData[pHeap->nSize];
	while (1)
	{
		if (lchild(i) <= pHeap->nSize && rchild(i) <= pHeap->nSize)
		{
			if (pHeap->nData[i] < Min(pHeap->nData[lchild(i)], pHeap->nData[rchild(i)]))
				break;
			if (pHeap->nData[lchild(i)] < pHeap->nData[rchild(i)])
			{
				Swap(&pHeap->nData[i], &pHeap->nData[lchild(i)]);
				i <<= 1;
			}
			else
			{
				Swap(&pHeap->nData[i], &pHeap->nData[rchild(i)]);
				i = ( i << 1 ) + 1;
			}
		}
		else
			break;
	}
	pHeap->nSize--;
	return nValue;
}
int main()
{
	Heap Myheap_1 = NULL;
	Heap Myheap_2 = NULL;

	InitializeHeap(&Myheap_1, 15);
	InitializeHeap(&Myheap_2, 15);

	for (int i = 0; i < 15; i++)
	{
		int temp = rand() % 571;
		Insert_Num_Use_Min(Myheap_1, temp);
		Insert_Num_Use_Max(Myheap_2, temp);
	}

	printf("小根堆中的元素为:\n");
	for (int i = 1; i <= Myheap_1->nSize; i++)
		printf("%d ", Myheap_1->nData[i]);
	
	printf("\n\n大根堆中的元素为:\n");
	for (int i = 1; i <= Myheap_1->nSize; i++)
		printf("%d ", Myheap_2->nData[i]);
	
	printf("\n\n依次弹出小根堆:\n");
	while (Myheap_1->nSize > 0)
	{
		printf("%d ", PopMin(Myheap_1));
	}

	printf("\n\n依次弹出大根堆:\n");
	while (Myheap_2->nSize > 0)
	{
		printf("%d ", PopMax(Myheap_2));
	}

	DestoryHeap(&Myheap_1);
	DestoryHeap(&Myheap_2);

	printf("\n\n");
	system("pause");

	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: