堆的基本操作及应用--优先级队列和堆排

Heap.h
typedef int DataType;
typedef int (*Compare)(DataType, DataType);
typedef struct Heap 
{ 
	DataType* _array; 
	int _capacity; 
	int _size; 
	Compare _com;
}Heap; 


#define MAX_SIZE 10

void InitHeap(Heap* hp, Compare com);
// 创建堆 
void CreateHeap(Heap* hp, DataType* array, int size); 

// 在堆中插入值为data的元素 
void InsertHeap(Heap* hp, DataType data); 

// 获取堆顶元素 
DataType TopHeap(Heap* hp); 

// 检测一个堆是否为空堆 
int EmptyHeap(Heap* hp); 

// 获取堆中元素的个数 
int SizeHeap(Heap* hp); 

// 删除堆顶元素 
void DeleteHeap(Heap* hp); 

// 销毁堆 
void DestroyHeap(Heap* hp); 

// 小堆 
int Less(DataType left, DataType right); 

// 大堆 
int Greater(DataType left, DataType right); 

void testHeap();

Heap.c
#include "Heap.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

void InitHeap(Heap* hp, Compare com)
{
	if(hp==NULL)
		return;
	hp->_array =(DataType *)malloc(sizeof(DataType)*MAX_SIZE);
	if(hp->_array ==NULL)
		printf("申请空间失败\n");
	hp->_size =0;
	hp->_com =com;
}
void Swap(int *m,int *n)
{
	int tmp=*m;
	*m=*n;
	*n=tmp;
}

void CheckCapacity(Heap* hp)
{
	DataType* pNewCapacity=NULL;
	if(hp==NULL)
		return;
    pNewCapacity=(DataType *)malloc(sizeof(DataType)* hp->_capacity *2);
	if(pNewCapacity==NULL)
		printf("扩容失败\n");

}

void AdjustUp(Heap* hp,DataType child)
{
	int parent=(child-1)>>1;
	if(hp==NULL)
		return;
	while(child)
	{
		if(hp->_com(hp->_array[child],hp->_array[parent]))
		{
			Swap(&hp->_array[parent],&hp->_array[child]);
			child=parent;
			parent=(child-1)>>1;
		}
		else
			break;
	}

}

void AdjustDown(Heap* hp,DataType parent)
{
	int child=parent*2+1;
	if(hp==NULL)
		return;

	while(child<hp->_size)
	{
		if(hp->_com(hp->_array[child+1],hp->_array[child])&& child+1<hp->_size )
		{
			child=child+1;
		}

		if(hp->_com(hp->_array[child],hp->_array[parent]))
		{
			Swap(&hp->_array[child],&hp->_array[parent]);
			parent=child;
			child=parent*2+1;
		}
		else
			break;
	}
}

// 创建堆 
void CreateHeap(Heap* hp, DataType* array, int size)
{
	int i=0;
	int root=0;
	assert(hp);

	//1.给堆申请空间
	hp->_array =(DataType *)malloc(sizeof(DataType)*MAX_SIZE);
	if(hp->_array ==NULL)
		printf("申请空间失败\n");
	hp->_capacity =MAX_SIZE;
	hp->_size =0;

	//2.放置元素
	for(;i<size;++i)
	{
		hp->_array[i]=array[i];
		hp->_size++;
	}
	hp->_size =size;

	//3.调整
	root=(size-2)>>1;  //最后一个非叶子节点
	for(;root>=0;root--)
		AdjustDown(hp,root);
}


// 在堆中插入值为data的元素 
void InsertHeap(Heap* hp, DataType data)
{
	if(hp==NULL)
		return;
	//1.容量检测
	if(hp->_size ==hp->_capacity )
	{
		CheckCapacity(hp);
	}
	//2.插入元素:把元素放入最后一个元素之后
	hp->_array[hp->_size]=data;
	hp->_size++;
	
	//3.调整元素
	if(hp->_size >1)
		AdjustUp(hp,hp->_size -1);
}

// 获取堆顶元素 
DataType TopHeap(Heap* hp)
{
	if(hp==NULL)
		return -1;
	return hp->_array[0];
}

// 检测一个堆是否为空堆 
int EmptyHeap(Heap* hp)
{
	if(hp==NULL)
		return 1;
	return 0;
}

// 获取堆中元素的个数 
int SizeHeap(Heap* hp)
{
	if(hp==NULL)
		return 0;
	return hp->_size ;
}

// 删除堆顶元素 
void DeleteHeap(Heap* hp)
{
	if(hp==NULL)
		return;
	//1.堆顶元素换到最后一个元素
	Swap(&hp->_array[0],&hp->_array[hp->_size-1]);
	hp->_size--;
	//2.向下调整
	AdjustDown(hp,0);
}

// 销毁堆 
void DestroyHeap(Heap* hp)
{
	assert(hp);
	if(EmptyHeap(hp))
		return;
	hp->_size =0;
	hp->_com =NULL;
}

// 小堆 
int Less(DataType left, DataType right)
{
	return left<right;
}

// 大堆 
int Greater(DataType left, DataType right)
{
	return left>right;
}

void AdjustHeap(int *array,int size,int parent,Compare com)
{
	int child =(parent<<1)+1;

	while(child<size)
	{
		if(child+1 <size && com(array[child+1],array[child]))
		{
			child+=1;
		}

		if(com(array[child],array[parent]))
		{
			Swap(&array[child],&array[parent]);

			parent=child;
			child =(parent<<1)+1;
		}
		else
			break;
	}
}

void HeapSort(int *array,int size,Compare com)
{
	int root=(size-2)>>1;
	int end=size-1;
	
	//调整
	while(root>=0)
	{
		AdjustHeap(array,size,root,com);
		root--;
	}
	
	//最后一个结点与根节点交换后end--,当根节点不满足性质时,进行调整
	while(end>0)
	{
		Swap(&array[0],&array[end]);
		AdjustHeap(array,end,0,com);
		end--;
	}
}



void Heap_Print(int *array,int size)
{
	int i=0;
	for(;i<size;i++)
	{
		printf("%d ",array[i]);
	}
	printf("\n");
}

void testHeap()
{
	Heap hp;
	int arr[]={53,17,78,9,5,65,87,23,31};
	int size=sizeof(arr)/sizeof(arr[0]);
    InitHeap(&hp,Greater);
	CreateHeap(&hp,arr,size);
	InsertHeap(&hp,13);
	printf("top=%d\n",TopHeap(&hp));
	printf("size=%d\n",SizeHeap(&hp));
	DestroyHeap(&hp);
}


void testHeapSort()
{
	int arr[]={53,17,78,9,5,65,87,23,31};
	Heap_Print(arr,sizeof(arr)/sizeof(arr[0]));
	HeapSort(arr,sizeof(arr)/sizeof(arr[0]),Less);
	Heap_Print(arr,sizeof(arr)/sizeof(arr[0]));
}

PriorityQueue.h
#include "Heap.h"
typedef struct PriorityQueue 
{ 
	Heap _hp; 
}PriorityQueue; 

// 优先级队列初始化 
void PriorityQueueInit(PriorityQueue* q, Compare com); 

// 向队列中插入元素 
void PriorityQueuePush(PriorityQueue* q, DataType data); 

// 删除优先级最高的元素 
void PriorityQueuePop(PriorityQueue* q); 

// 获取队列中元素个数
int PriorityQueueSize(PriorityQueue* q); 

// 检测优先级队列是否为空 
int PriorityQueueEmpty(PriorityQueue* q); 

// 获取堆顶的元素 
DataType PriorityQueueTop(PriorityQueue* q); 

// 销毁优先级队列 
void PriorityQueueDestroy(PriorityQueue* q); 

void testPriorityQueue();

PriorityQueue.c
#include "PriorityQueue.h"
#include <stdio.h>

// 优先级队列初始化 
void PriorityQueueInit(PriorityQueue* q, Compare com)
{
	InitHeap(&q->_hp ,com);
}

// 向队列中插入元素 
void PriorityQueuePush(PriorityQueue* q, DataType data)
{
	InsertHeap(&q->_hp,data);
}

// 删除优先级最高的元素 
void PriorityQueuePop(PriorityQueue* q)
{
	DeleteHeap(&q->_hp );
}

// 获取队列中元素个数 
int PriorityQueueSize(PriorityQueue* q)
{
	return SizeHeap(&q->_hp );
}

// 检测优先级队列是否为空 
int PriorityQueueEmpty(PriorityQueue* q)
{
	return EmptyHeap(&q->_hp );
}

// 获取堆顶的元素 
DataType PriorityQueueTop(PriorityQueue* q)
{
	return TopHeap(&q->_hp );
}

// 销毁优先级队列 
void PriorityQueueDestroy(PriorityQueue* q)
{
	DestroyHeap(&q->_hp );
}

void testPriorityQueue()
{
	PriorityQueue q;
	PriorityQueueInit(&q,Greater);
	PriorityQueuePush(&q,4);
	PriorityQueuePush(&q,1);
	PriorityQueuePush(&q,67);
	PriorityQueuePush(&q,34);
	PriorityQueuePush(&q,23);
	PriorityQueuePush(&q,78);

	printf("top=%d\n",PriorityQueueTop(&q));
	printf("size=%d\n",PriorityQueueSize(&q));

	PriorityQueuePop(&q);
	PriorityQueuePop(&q);
	printf("top=%d\n",PriorityQueueTop(&q));
	printf("size=%d\n",PriorityQueueSize(&q));

}

test.c
#include <stdio.h>

int main()
{
	//testHeap();
	//testPriorityQueue();
	testHeapSort();
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值