关于堆知识点的整理

首先堆不是内存中的一片区域,而是一种数据结构。
1.堆的概念:如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
2.堆的性质:

  • 堆是一颗完全二叉树
  • 常常用数组实现
  • 堆中某个节点的值总是不大于或者不小于其父节点的值
  • 堆的基本功能:找最值
    3.数据结构中堆与内存堆区的区别:数据结构中的堆:堆是一种经过排序的树形数据结构,每个节点都有一个值。通常我们所说的堆的数据结构是指二叉树。堆的特点是根节点的值最小(或最大),且根节点的两个树也是一个堆。
    内存中的堆:堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
    4.堆的图示
    在这里插入图片描述
    5.堆的实现
    (1)创建堆
    创建堆过程:在创建堆是就是把数组的元素建成一个完全二叉树,然后利用向下调整,使二叉树成为最大堆或者最小堆。
    代码实现:
//向下调整
void heapify( int* array, int size,int index)
{
	int left = 2 * index + 1;//该节点左孩子的下标
	int right = 2 * index + 2;//该节点右孩子的下标
	if (left >= right)
	{
		return;
	}
	int min = left;
	if (right < size && array[right] < array[left])
	{
		min = right;
	}
	if (array[index] <= array[min])
	{
		return;
	}
	int t = array[min];
	array[min] = array[index];
	array[index] = t;

	index = min;

	heapify(array, size, min);
}
// 创建堆 
void CreatHeap( int* array, int size)
{
	for (int i = (size - 2)/2; i >= 0; i--)
	{
		heapify(array, size, i);
	}
}

(2)堆的初始化

void InitHeap(Heap* hp,int* array,int size)
{
	for (int i = 0; i < size; i++) {
		hp->_array[i] = array[i];
	}
	hp->_size = size;

	createHeap(hp->_array, hp->_size);
}

(3)向堆中插入值为data的元素

// 向堆中插入值为data的元素 
void InsertHeap(Heap* hp, DataType data)
{
	if (hp == NULL)
	{
		return;
	}
	hp->_array[hp->_size++] = data;
	heapify(hp->_array, hp->_size,hp->_size - 1);
}

(4)删除堆顶元素
删除堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。

// 删除堆顶元素 
void EraseHeap(Heap* hp)
{
	assert(hp->_size > 0);
	if (hp == NULL)
	{
		return;
	}
	hp->_array[0] = hp->_array[hp->_size - 1];
	hp->_size--;
	heapify(hp->_array, hp->_size, 0);
}

(5)获取堆中有效元素

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

(6)检测堆是否为空

// 检测堆是否为空 
int EmptyHeap(Heap* hp)
{
	if (hp == NULL)
	{
		return;
	}
	return hp->_size = 0 ? 1 : 0;
}

(7)获取堆顶元素

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

(8)销毁堆

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

6.堆的应用
(1)堆排序
基本思想:堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。排升序要建大堆,排降序建小堆。
排序展示:
在这里插入图片描述
代码实现:

//堆排序
//1.建大堆
void swap(int *a, int *b) {
	int t = *a;
	*a = *b;
	*b = t;
}

void heapify(int array[], int size, int index)
{
	int left = 2 * index + 1;
	int right = 2 * index + 2;
	if (left >= size)
	{
		return;
	}
	int max = left;
	if (right < size &&array[right] > array[left])
	{
		max = right;
	}
	if (array[index] >= array[max])
	{
		return;
	}
	int t = array[max];
	array[max] = array[index];
	array[index] = t;

	index = max;
	heapify(array, size, max);
}
void createHeap(int array[], int size)
{
	for (int i = (size - 2) / 2; i >= 0; i--)
	{
		heapify(array, size, i);
	}
}
void heapSort(int array[], int size)
{
	createHeap(array, size);
	for (int i = 0; i < size; i++)
	{
		int t = array[0];
		array[0] = array[size - i-1];
		array[size - 1 - i] = t;
		heapify(array, size - i - 1, 0);
	}
}

(2)topK问题
TopK问题是指从大量数据(源数据)中获取最大(或最小)的K个数据。
获取最大值:建小堆
获取最小值:建大堆

发布了31 篇原创文章 · 获赞 2 · 访问量 843

猜你喜欢

转载自blog.csdn.net/qq_42430426/article/details/96866563