堆 练习

##以大堆为例:
###heap.h

#pragma once
#include<stdio.h>
#include<windows.h>
#include<assert.h>
typedef int HeapDataType;

typedef struct heap//堆在物理结构上看就是一个数组,只是我们把他抽象成树状结构
{
	HeapDataType *_array;//数组指针
	size_t size;//当前个数
	size_t capacity;//最大容量
}heap;

void HeapAdjustDown(heap *hp, int root)
{
	assert(hp);
	assert(root < (int)(hp->size));
	int parent = root;
	int child = root * 2 + 1;
	while (child < (int)(hp->size))
	{
		if (child + 1 < (int)(hp->size) && hp->_array[child + 1] > hp->_array[child])
		{
			child++;
		}
		if (hp->_array[parent] < hp->_array[child])
		{
			HeapDataType tmp = hp->_array[child];
			hp->_array[child] = hp->_array[parent];
			hp->_array[parent] = tmp;
		}
		parent = child;
		child = parent * 2 + 1;
	}

}
//从child下标的成员向上调整,在插入数据中用到
void HeapAdjustUp(heap *hp, int child)
{
	assert(hp);
	int parent = (child - 1) / 2;
	while (parent)
	{
		if (hp->_array[parent] < hp->_array[child])
		{
			HeapDataType tmp = hp->_array[child];
			hp->_array[child] = hp->_array[parent];
			hp->_array[parent] = tmp;

		}
		child = parent;
		parent = (child - 1) / 2;
	}
	if (hp->_array[parent] < hp->_array[child])
	{
		HeapDataType tmp = hp->_array[child];
		hp->_array[child] = hp->_array[parent];
		hp->_array[parent] = tmp;

	}
	child = parent;
	parent = (child - 1) / 2;
}
//堆的初始化
void HeapInit(heap *hp, HeapDataType *_arr, size_t size)
{
	//给hp->_array开辟等同于数组arr的空间,吧arr的值依次给给array即可
	assert(_arr);
	assert(size > 0);
	hp->_array = (HeapDataType *)malloc(sizeof(HeapDataType)*size);
	assert(hp->_array);
	HeapDataType *cur = hp->_array;
	hp->size = size;
	hp->capacity = size;
	for (size_t i = 0;i < size;i++)
	{
		cur[i] = _arr[i];
	}
}

//往堆中新插入数据,需考虑增容问题,插入新数据后堆仍然不改变排列规则
void HeapPush(heap *hp, HeapDataType x)
{
	assert(hp);
	if (hp->size == hp->capacity)
	{
		hp->capacity *= 2;
		hp->_array = realloc(hp->_array, hp->capacity * sizeof(HeapDataType));
	}
	hp->_array[hp->size] = x;

	HeapAdjustUp(hp, (int)(hp->size));
	hp->size++;
}
//删除堆顶数据,删除后仍不改变排列规则
void HeapPop(heap *hp)
{
	assert(hp);
	if (hp->size == 0)
	{
		printf("the heap is empty");
		return;
	}
	hp->_array[0] = hp->_array[hp->size - 1];
	hp->size--;
	HeapAdjustDown(hp, 0);

}
//返回堆中的数据个数
size_t Heap_Size(heap *hp)
{
	assert(hp);
	return hp->size;
}
//判断堆是否为空,为空返回1,非空返回0
int HeapEmpty(heap *hp)
{
	assert(hp);
	if (hp->size == 0)
	{
		return 1;
	}
	return 0;
}
//返回堆的堆顶数据,(这是堆的意义所在,能在海量数据中提取最大或最小且高效)
HeapDataType HeapTop(heap *hp)
{
	assert(hp);
	assert(hp->size);
	
	return hp->_array[0];
}
//堆排序 
void HeapSort(heap *hp)
{
	assert(hp);
	int root = (hp->size - 1 - 1) / 2;
	int child = hp->size - 1;
	while (root>=0)
	{
		HeapAdjustDown(hp, root);
		root--;
	}

}
//从root下标的成员向下调整,向下调整的前提是他和她的左右孩子已经构成大(小)堆。




###test.c




#include"heap.h"

void test()
{
	heap hp;
	HeapDataType arr[] = { 9,17,65,23,45,78,87,53,31 };
	HeapDataType arr1[] = { 87,78,53,45,65,9,31,17,23 };
	size_t size1 = sizeof(arr) / sizeof(HeapDataType);
	HeapInit(&hp, arr, size1);
	HeapSort(&hp);
	HeapPush(&hp, 50);
	HeapPop(&hp);

	for (size_t i = 0;i < (hp.size);i++)
	{
		printf("%d ", hp._array[i]);
	}
	printf("\n堆数据个数%u", Heap_Size(&hp));
	printf("\n堆顶元素:%d", HeapTop(&hp));
	printf("\n是否为空:%d", HeapEmpty(&hp));


}

int main()
{
	test();
	system("pause");
	return 0;
}
### Python 实现排序 排序是一种基于二叉数据结构的比较型排序算法。该算法通过构建最大来逐步将最大的元素移动到列表末端,从而实现升序排列。 #### 构建最大函数 `sift` 为了使保持最大性质,在每次交换根节点与最后元素之后都需要重新调整: ```python def sift(arr, start, end): root = start while True: child = 2 * root + 1 # 左孩子索引 if child > end: # 如果左孩子超过了范围,则结束循环 break if child + 1 <= end and arr[child] < arr[child + 1]: child += 1 # 右孩子的值更大则指向右孩子 if arr[root] < arr[child]: # 若父节点小于较大子节点,则交换两者位置并继续向下筛选 arr[root], arr[child] = arr[child], arr[root] root = child else: break ``` 此部分代码实现了自顶向下的化操作,确保当前树满足最大特性[^3]。 #### 完整排序过程 完整的排序不仅涉及上述提到的最大维护逻辑,还需要先初始化整个序列形成初始大根,并反复执行移除最大值的操作直到所有元素都被处理完毕: ```python def heap_sort(arr): n = len(arr) # 初始化最大 for i in range((n-2)//2, -1, -1): sift(arr, i, n-1) # 进行排序 for j in range(n-1, 0, -1): arr[j], arr[0] = arr[0], arr[j] # 将最大值移到数组末尾 sift(arr, 0, j-1) # 对剩余未排序的部分再次进行化 ``` 这段程序展示了如何利用之前定义好的`sift`方法来进行实际的数据排序工作。 #### 测试实例 下面给出一段简单的测试代码用于验证上面编写的排序功能是否正常运作: ```python if __name__ == "__main__": test_array = list(range(10)) import random random.shuffle(test_array) print("原始乱序:", test_array) heap_sort(test_array) print("排序结果:", test_array) ``` 运行以上脚本将会输出一组随机打乱后的数字以及经过排序整理过的结果,以此证明所编写的方法能够正确地对输入数据集实施有效的排序操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值