算法训练-堆

1、堆

在这里插入图片描述
在这里插入图片描述

堆代码实现与堆排序

#include<iostream>
#include<queue>
#include <math.h>
using namespace std;

#define MAX_HEAP_SIZE 11

/************************************************************************/
/*

6
3#4
1#9    2#8
10#7    5#    ##     ##


*/
/************************************************************************/

typedef union myheap
{
	int m_size;
	int m_heapmem[MAX_HEAP_SIZE];
}*ptrHeap;

void init_heap(ptrHeap* heap, int size = 10){
	if (size + 1>MAX_HEAP_SIZE)
	{
		printf("out of memery\n"); return;
	}
	*heap = (ptrHeap)malloc(sizeof(myheap));
	int temp[10] = { 6, 3, 4, 1, 9, 2, 8, 10, 7, 5 };
	(*heap)->m_size = size;
	for (int i = 0; i < size; ++i)
	{
		(*heap)->m_heapmem[i + 1] = temp[i];
	}
}
void swap(int& a, int& b){
	if (a == b)
	{
		return;
	}
	a = a^b;
	b = a^b;
	a = a^b;
}

//完全二叉树 逐层层序遍历,堆在数组中存储时的程序遍历只需遍历一遍数组即可,时间复杂度为O(n)
/*
教训总结:
写代码前一定要想将思路理顺了,跟着逻辑走,而不要跟着记忆走,“隐约的记得好像其他类似的做法是这样的”这样的思维方式很有问题,抓不住问题的本质,即使顺着记忆做出来了,下次也可能会忘记,
而且容易沉溺于“想不起上次的做法”而苦恼的境地。

*/
void dump_heap(ptrHeap heap){
	int size = heap->m_size;
	queue<int> level;
	level.push(heap->m_heapmem[1]);

	int i = 0;
	int le = 0;
	while (i<size)
	{
		while (!level.empty())
		{
			printf(" %d ", level.front()); level.pop();
			i++;
		}
		printf("\n");

		//找到各层结点的开始下标和结束下标(太傻叉了 这个实现,完全没有必要用队列啊)
		for (int j = i / 2 + 1; j < i / 2 + 1 + (int)pow(2, le) && 2 * j <= size; ++j)
		{
			level.push(heap->m_heapmem[j * 2]);
			if (2 * j + 1 <= size)
			{
				level.push(heap->m_heapmem[j * 2 + 1]);
			}
		}
		le++;
	}
}


void dump_heap2(ptrHeap heap)
{
	int size = heap->m_size;
	int maxlevel = size / 2;
	int count = 0;
	//找到各层的起点和终点下标,然后进行遍历
	for (int level = 0; level < maxlevel && count < size; ++level){
		int startIndex = (1 << level)            /* (int)pow(2, level)*/;
		int endIndex = startIndex + (1 << level) /*(int)pow(2, level)*/;

		for (; startIndex < endIndex && startIndex<=size; ++startIndex){
			printf("%d ", heap->m_heapmem[startIndex]);
			count++;
		}
		printf("\n");
	}
}

void heapify(ptrHeap* heap, int parent,int size){
	int maxIndex = 0;
	int left = 0;
	int right = 0;
	while (true)
	{
		maxIndex = parent;
		left = parent * 2;
		right = left + 1;

		if ((*heap)->m_heapmem[maxIndex] < (*heap)->m_heapmem[left] && (left <= size)){
			maxIndex = left;
		}
		if ((*heap)->m_heapmem[maxIndex] < (*heap)->m_heapmem[right] && (right <= size)){
			maxIndex = right;
		}
		if (maxIndex == parent){
			break;
		}
		swap((*heap)->m_heapmem[parent], (*heap)->m_heapmem[maxIndex]);
		parent = maxIndex;
	}
}
void dump(ptrHeap heap){
	printf("\n");
	int size = heap->m_size;
	for (int i = 1; i <= size; ++i){
		printf(" %d ", heap->m_heapmem[i]);
	}
	printf("\n");
}
void build_heap(ptrHeap heap)
{
	int size = heap->m_size;
	for (int i = size / 2; i > 0; --i){
		heapify(&heap, i,size);
	}
}
void heap_sort(ptrHeap pHeap){
	
	int size = pHeap->m_size;
	while (size>1)
	{
		//堆化
		for (int i = size / 2; i > 0; --i){
			heapify(&pHeap, i,size);
		}
		//堆化后将最大元素(第一个元素)放在最后一位
		swap(pHeap->m_heapmem[1], pHeap->m_heapmem[size]);
		size--;
	}

}


int main()
{
	ptrHeap pHeap = nullptr;
	cout << "before build heap:" << endl;
	init_heap(&pHeap);
	dump_heap2(pHeap);
	cout << "after build heap:" << endl;
	build_heap(pHeap);
	dump_heap2(pHeap);

	printf("before heap sort:\n");
	dump(pHeap);
	printf("after heap sort:\n");
	heap_sort(pHeap);
	dump(pHeap);
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片微型计算机(MCU)经过多年的发展,在性能上有很大的进步,在型号上发展到上千种类,已经广泛应用于人类社会生活的各个领域。单片机课程已经成为高校计算机、自动化、测控以及电子信息工程等专业的重要课程。该课程是一门理论性和实践性都很强的课程,在实际教学中,应将理论教学和实验教学紧密结合。学生在掌握理论知识之余,必须通过编写程序、设计硬件电路、仿真、调试这一系列的实验过程,才能更好地掌握单片机的结构原理和应用技能。随着单片机及其接口技术的飞速发展,目前市场上供应的编程仿真实验资源并不能完全满足高校单片机课程教与学的需求,构建低成本、技术先进、源码公开的单片机编程仿真实验系统,对我国单片机课程的教学和单片机领域人才的培养具有重要的现实意义。 本论文结合目前教学中对单片机编程仿真实验系统的实际需求,采用模块化结构设计思想,精心设计和开发了单片机编程仿真实验系统。该单片机编程仿真实验系统由PC机端单片机编程控制软件和单片机编程仿真实验板两部分组成。PC机端的单片机编程控制软件可以自动检测到连接到单片机编程仿真实验板上的单片机,控制单片机编程器擦除、写入、读出、校验目标单片机ROM中的程序,以十六进制文件(.HEX文件)格式显示在控制界面内;单片机仿真实验系统能够把写入单片机的程序实时地运行,并呈现实际运行效果。单片机编程控制软件和单片机仿真实验板组成一个完整的单片机编程仿真实验系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值