堆实现代码

Posted 水澹澹兮生烟.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆实现代码相关的知识,希望对你有一定的参考价值。

  • heap.h
#pragma once
typedef int DType;
//函数指针的类型定义
typedef int (*PCOM)(DType left, DType right);

typedef struct  heap
{
	DType* array;
	int capacity;
	int size;
	PCOM pcom;//函数指针变量-->指向所有比较的函数
}heap;

int less(DType left, DType right);//比较函数
//初始化
heap* heapInit(heap* hp, DType*array, int size,PCOM pcom);

//插入
void heapInsert(heap* hp, DType data);
//删除
void heapdel(heap* hp);
//获取堆顶元素
DType heaptopdata(heap* hp);
//检测是否为空
int heapempty(heap* hp);
//获取堆里有效元素的个数
int heapsize(heap* hp);
//对的销毁
void heapdestory(heap* hp);
void adjust(heap* hp, int parent);
void swap(DType* left, DType* right);
void adjustup(DType* hp);
  • heap.c
#include"heap.h"

#include<assert.h>
#include<malloc.h>
#include<stdio.h>
int less(DType left, DType right){
	return left > right;
}
void swap(DType* left, DType* right){
	int temp = *left;
	*left = *right;
	*right = temp;
}
//初始化
heap* heapInit(heap* hp, DType*array, int size, PCOM pcom){
	assert(hp);
	int lastnotleaf = 0;
	hp->array = (DType*)malloc(sizeof(DType)*size);
	if (NULL == hp->array){
		return NULL;
	}	
	hp->capacity = size;
	//memcpy(hp->array, array, sizeof(sizeof(DType)*size));//以字节为准进行拷贝,大小为(sizeof(DType)*capa)
	for (int i = 0; i < size; i++){
		hp->array[i] = array[i];
	}

	hp->size = size;
	hp->pcom = pcom;//有了这种比较方式

	//找到非叶子结点
	lastnotleaf = ((size - 1) - 1) / 2;
	//从该结点位置逐个往前直到根
	for (int root = lastnotleaf; root >= 0; root--){
		adjust(hp, root);
	}
	return hp;
}
void adjustup(heap* hp){
	DType* array = hp->array;
	int size = hp->size;
	int child = size-1;
	int parent = (child - 1) / 2;
	while (child){
		if (hp->pcom(array[child] , array[parent]))
		{
			swap(&array[child], &array[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}

		else return;
	}
}
//调整
void adjust(heap* hp, int parent){
	DType* array = hp->array;
	int size = hp->size;
	//默认让child标记左孩子,因为parent可能不存在右孩子
	int child = parent * 2 + 1;
	while (child<size){
		//右孩子存在的情况:
		if (child + 1<size&&hp->pcom(array[child + 1],array[child])) //要注意&&两边的先后次序,如果比较左右孩子放在前面,会造成访问越界
		{
			child += 1;//让child标记右孩子
		}
		//检测parent是否满足情况
		if (hp->pcom(array[child],array[parent])){
			swap(&array[child], &array[parent]);
			//较大的双亲和孩子交换后,可能会导致子树不满足
			parent = child;
			child = parent * 2 + 1;
		}
		else{
			//如果双亲比孩子节点还小
			return;
		}
	}
}

//插入
void heapInsert(heap* hp, DType data){
	//首先确定堆是否已满
	if (hp->size == hp->capacity){
		//已满先进行扩容
		hp->array = (DType*)realloc(hp->array,sizeof(DType)*(hp->capacity)*2);
		if (NULL == hp->array){
			assert(0);
			return;
		}
		hp->capacity *= 2;
	}
	//先将data插入堆中
	hp->array[hp->size++] = data;
	//然后对插入后的孩子节点与其父节点进行比较,调换
	adjustup(hp);
}
//删除
void heapdel(heap* hp){
	//判断堆是否为空
	if (heapempty(hp)) return;
	//交换堆顶和堆尾元素
	swap(&hp->array[0], &hp->array[hp->size - 1]);
	//有效个数-1
	hp->size -= 1;
	//对现在的二叉树进行重新排序,再次成堆
	adjust(hp, 0);
}
//获取堆顶元素
DType heaptopdata(heap* hp){
	assert(!heapempty(hp));
	return hp->array[0];
}
//检测是否为空
int heapempty(heap* hp){
	assert(hp);
	return 0 == hp->size;
}
//获取堆里有效元素的个数
int heapsize(heap* hp){
	assert(hp);
	return hp->size;
}
//对的销毁
void heapdestory(heap* hp){
	assert(hp);
	if (hp->array){
		free(hp->array);
		hp->array = NULL;
		hp->capacity = 0;
		hp->size = 0;
	}
}

  • test.c
#include<stdio.h>
#include"heap.h"
int main(){
	int array[] = {2,3,4,5,6,7,8};
	heap hp;
	int size = sizeof(array) / sizeof(array[0]);
	heapInit(&hp, array, size,less);
	printf("size=%d\\n", heapsize(&hp));
	printf("top=%d\\n", heaptopdata(&hp));

	//heapInsert(&hp, 10);
	heapdel(&hp);
	printf("size=%d\\n", heapsize(&hp));
	printf("top=%d\\n", heaptopdata(&hp));
	for (int i = 0; i < hp.size; i++)
	{
		printf("%d\\t", hp.array[i]);
	}
	printf("\\n");
	heapInsert(&hp, 1);
	printf("size=%d\\n", heapsize(&hp));
	printf("top=%d\\n", heaptopdata(&hp));
	for (int i = 0; i < hp.size; i++)
	{
		printf("%d\\t", hp.array[i]);
	}
}
  • 运行结果:

大堆:在这里插入图片描述

小堆:
在这里插入图片描述

以上是关于堆实现代码的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 - Golang 实现集合操作

代码片段 - Golang 实现简单的 Web 服务器

python代码实现堆排序

ASP.net MVC 代码片段问题中的 Jqgrid 实现

notepad++怎么实现一键自动完成一堆代码

选择排序(简单选择排序堆排序的算法思想及代码实现)