C语言数据结构---堆

本文详细介绍了一种数据结构——小根堆的实现原理及应用。小根堆是一种特殊的完全二叉树,常用于高效地查找和维护一组数据中的最小元素。文章通过具体的代码示例,展示了如何创建、插入元素、调整堆结构以及删除指定元素等操作。
摘要由CSDN通过智能技术生成

堆通常是一个可以被看做一棵树的数组对象。

/****************************************************************************
*Project:Heap 堆
*Author:Rise
*Note:这里是小根堆
*堆通常是一个可以被看做一棵树的数组对象。
*****************************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<memory.h>
#include<malloc.h>
#include<time.h>
#include<math.h>
#include<stdbool.h>
#include<vld.h>

#pragma pack(4)	//4字节对齐

#define INIT_SIZE 20

typedef struct heap
{
	int* _array;
	int index;
	size_t size;
}*pheap, minheap, maxheap,heap;

void addMinHeap(minheap* mh, int data);

void CreateMinHeap(minheap* mh)
{
	mh->size = INIT_SIZE;
	mh->_array = (int*)malloc(sizeof(int) * mh->size);
	memset(mh->_array, 0, _msize(mh->_array));
	mh->index = -1;
}

void FreeMinHeap(minheap* mh)
{
	if (mh->_array != NULL)
	{
		free(mh->_array);
		mh->_array = NULL;
	}

	mh->size = 0;
	mh->index = -1;
}

inline bool isFullMinHeap(minheap* mh)
{
	return mh->index == mh->size - 1;
}
bool isEmptyMinHeap(minheap* mh)
{
	return mh->index == -1;//-1表示空,没有写入数据
}

int getFloorMinHeap(minheap* mh)
{
	return (int)floor(log2(mh->index)) + 1;
}

int bottomMaxMinHeap(minheap* mh)
{
	return (int)pow(2, (double)(getFloorMinHeap(mh) - 1));
}

int findData(minheap* mh,const int data)
{
	for (int i = 0; i <= mh->index; ++i)
	{
		if (data == mh->_array[i])
			return i;
	}
	return -1;
}

void adjustup(minheap* mh,const int index)
{
	int cur = index;
	int dad = (cur - 1) / 2;
	int temp = mh->_array[cur];
	while (cur > 0)
	{
		if (mh->_array[dad] < mh->_array[cur])
			break;
		mh->_array[cur] = mh->_array[dad];
		cur = dad;
		dad = (cur - 1) / 2;
	}
	mh->_array[cur] = temp;
}

void adjustdown(minheap* mh,const int index)
{
	int cur = index;
	int son = cur * 2 + 1;//左子节点
	int temp = mh->_array[cur];
	while(son<mh->index)
	{
		//son<mh->index确保有右子节点;mh->_array[son]>mh->_array[son+1]选左右节点中最小的
		if (son<mh->index && mh->_array[son]>mh->_array[son + 1])
			son++;
		if (temp < mh->_array[son])
			break;
		else
		{
			mh->_array[cur] = mh->_array[son];
			cur = son;
			son = cur * 2 + 1;
		}
	}
	mh->_array[cur] = temp;
}



void addMinHeap(minheap* mh, int data)
{
	if (mh->size > mh->index + 1)
	{
		mh->_array[mh->index + 1] = data;
		mh->index++;
		adjustup(mh, mh->index);
	}
	else
	{
		int* tmp = mh->_array;
		mh->_array = (int*)malloc(sizeof(int) * (mh->size + 3));	//随着数据越来越大,很容易分配失败;
		memcpy(mh->_array, tmp, _msize(tmp));
		free(tmp);

		mh->_array[mh->index + 1] = data;
		mh->index++;
		adjustup(mh, mh->index);
	}
}

bool deleteMinHeap(minheap* mh,const int data)
{
	if (mh->index < 0)
		return false;
	int index = findData(mh, data);
	if (index == -1)
		return false;
	//与最后一个元素交换,再删最后一个元素
	mh->_array[index] = mh->_array[mh->index];
	mh->_array[mh->index] = 0;
	mh->index--;
	adjustdown(mh, index);
	return true;
}


void printHeapArray(heap h)
{
	for (int i = 0; i <= h.index; i++)
	{
		printf("%d ", h._array[i]);
	}
	printf("\n");
}
/********************堆排序************************************************/
void printArray(int h[], int count)
{
	for (int i = 0; i < count; i++)
	{
		printf("%d ", h[i]);
	}
	printf("\n");
}
void adjustupMinHeap(int h[], int count, int index)
{
	int tmp = h[index];
	int cur = index;
	int dad = (cur - 1) / 2;
	
	while(cur > 0 )
	{
		if (h[dad] < h[cur])
			break;
		h[cur] = h[dad];
		cur = dad;
		dad = (cur - 1) / 2;
	}
	h[cur] = tmp;
}
void SortMinHeap(int h[], int count)
{
	for (int i = 0; i < count; i++)
	{
		adjustupMinHeap(h, i + 1, i);
	}
}
/**************************************************************************/

int main()
{
	int arr[] = { 10,20,30,41,45,24,38,39,50,88,86,101 };
	minheap mp;
	CreateMinHeap(&mp);
	for (int i = 0; i < 12; i++)
		addMinHeap(&mp, arr[i]);
	printHeapArray(mp);
	//deleteMinHeap(&mp, 10);
	//printHeapArray(mp);
	FreeMinHeap(&mp);

	printArray(arr, 12);
	SortMinHeap(arr, 12);
	printArray(arr, 12);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Risehuxyc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值