堆的概念,创建,插入,删除以及堆排序

堆的概念

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:   Ki <= K2*i+1 且 Ki<= K2*i+2 (Ki >= K2*i+1 且 Ki >= K2*i+2) i = 0,1,2…,则称为小堆(或大堆)。

小堆(大堆)中:任一结点的关键码均小于(大于)等于它的左右孩子的关键 码,位于堆顶结点的关键码最小(最大),从根节点到每个结点的路径上数 组元素组成的序列都是递增(递减)的
堆存储在下标为0开始的数组中,因此在堆中给定下标为i的结点时:

  • 如果i=0,结点i是根节点,没有双亲节点;否则结点i的双亲结点为 结点(i-1)/2 
  • 如果2 * i + 1 <= n - 1,则结点i的左孩子为结点2 * i + 1,否则结 点i无左孩子
  • 如果2 * i + 2 <= n - 1,则结点i的右孩子为结点2 * i + 2,否则结 点i无右孩子

堆的创建,插入,删除,堆排序

代码实现

Heap.h

#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
typedef int HPDataType;
typedef struct Heap
{
	HPDataType* _a;
	int _size;
	int _capacity;
}Heap;

void HeapInit(Heap* hp, HPDataType* a, int n);
void HeapDestory(Heap* hp);
void HeapPush(Heap* hp, HPDataType x);
void HeapPop(Heap* hp);
HPDataType HeapTop(Heap* hp);
int HeapSize(Heap* hp);
int HeapEmpty(Heap* hp);

// 不要直接调Heap
void HeapSort(HPDataType* a, int n);
void HeapPrint(Heap* hp);

void TestHeap();

Heap.c

#include"Heap.h"
void Swap(HPDataType* x1, HPDataType*x2)
{
	HPDataType x = *x1;
	*x1 = *x2;
	*x2 = x;

}

void AdJustDown(HPDataType* a, int n, int root)
{
	int parent = root;
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1<n&&a[child]<a[child+1])
		{
			child++;
		}
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}
void AdJustUp(HPDataType*a, int child)
{
	assert(a);
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[parent] < a[child])
		{
			Swap(&a[parent], &a[child]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}


void HeapInit(Heap* hp, HPDataType* a, int n)
{
	assert(hp&&a);
	hp->_a = (HPDataType*)malloc(sizeof(HPDataType)*n);
	hp->_size = n;
	hp->_capacity = n;
	for (int i = 0; i < n; ++i)
	{
		hp->_a[i] = a[i];
	}
	//调堆
	for (int i = (n - 2) / 2; i >= 0; --i)
	{ 
		AdJustDown(hp->_a, hp->_size, i);
	}
}

void HeapDestory(Heap* hp)
{
	assert(hp);
	free(hp->_a);
	hp->_a = NULL;
	hp->_size = hp->_capacity = 0;
}

void HeapPush(Heap* hp, HPDataType x)
{
	assert(hp);
	if (hp->_capacity == hp->_size)
	{
		hp->_capacity *= 2;
		hp->_a = (HPDataType*)realloc(hp->_a,sizeof(HPDataType)*hp->_capacity);
	}
	hp->_a[hp->_size++] = x;
	AdJustUp(hp->_a, hp->_size - 1);
}

void HeapPop(Heap* hp)
{
	assert(hp);
	Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);
	hp->_size--;
	AdJustDown(hp->_a, hp->_size, 0);
}
HPDataType HeapTop(Heap* hp)
{
	assert(hp);
	return hp->_a[0];
}
int HeapSize(Heap* hp)
{
	assert(hp);
	return hp->_size;
}

int HeapEmpty(Heap* hp)
{
	assert(hp);
	return hp->_size > 0 ? 1 : 1;
}

//升序
void HeapSort(HPDataType* a, int n)
{
	//建大堆
	int i = 0;
	for (i = (n - 2) / 2; i >= 0; --i)
	{
		AdJustDown(a, n, i);
	}
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		//调堆 选次大的数
		AdJustDown(a, end, 0);
		--end;
	}
	return 0;
}
void HeapPrint(Heap* hp)
{
	for (int i = 0; i < hp->_size; ++i)
	{
		printf("%d ", hp->_a[i]);
	}
	printf("\n");
}
void TestHeap()
{
	Heap hp;
	HPDataType a[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };
	HeapInit(&hp, a, sizeof(a) / sizeof(a[0]));
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	HeapPush(&hp, 100);
	HeapPrint(&hp);
	HeapPop(&hp);
	HeapPrint(&hp);
	printf("%d \n", HeapSize(&hp));
	printf("%d \n", HeapTop(&hp));

}


int main()
{

	
	int a[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 }; 
	TestHeap();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Damn_Yang/article/details/84798483