C++类与对象------实现------堆

heap.h

#pragma once
#include<iostream>
using namespace std;

typedef int datatype;
class heap
{
public:
	heap(int a=4);	//构造,缺省值默认给4个空间的大小

	void push(datatype a);	//入数据

	void kuorong();	//扩容

	void swap(datatype& a, datatype& b);	//交换

	void adjustup();	//向上调整

	datatype deletetop();	//删除对顶数据并返回堆顶数据

	void adjustdown();	//向下调整

	datatype* heapsort();	//排个序

	~heap();	//析构

	void look();	//看一看堆的结构(用于测试观察,只能看4排)

	datatype* lty;	//堆的底层是个数组
	int size;		//堆中的数据个数
	int capacity;	//堆的容量
};

heap.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"heap.h"

void heap::look()		//看一看堆的结构
{
	cout << "              " << lty[0] << endl;
	int k = 1;

		if (k > 0 && k <= 2&&k<size)
		{
			for (; k < size && k <= 2; k++)
			{
				cout << "        " << lty[k];
			}
				cout << endl;
		}
		if (k > 2 && k <= 6)
		{
			for (; k < size && k <= 6; k++)
			{
				cout << "    " << lty[k];
			}cout << endl;
		}
		if (k > 6 && k <= 15)
		{
			for (; k < size && k <= 15; k++)
			{
				cout << "  " << lty[k];
			}cout << endl;
		}
		cout << endl << endl;
}


void heap::swap(datatype& a, datatype& b)	//交换
{
	datatype t = a;
	a = b;
	b = t;
}

heap::heap(int a)	//构造(缺省值只写在声明)
	:size(0),		//初始化列表会把类中的变量按声明的顺序初始化
	capacity(a)		//如果先开空间,size为随机值,所以不能把数组写在列表里。
{
	lty = new datatype[a]{0,0,0,0};		//随意初始化一下
}

heap::~heap()	//析构
{
	delete[]lty;
	lty = nullptr;
	size = capacity = 0;
}

void heap::push(datatype a)		//如数据
{
	if (size==capacity)			//空间不够需要扩容
	{
		(*this).kuorong();		//可以不用写*this
	}
	lty[size] = a;
	size++;
	look();						//查看一下是否入成功
	heap::adjustup();			//在数组末尾添加了数据需要向上调整
}


void heap::kuorong()			//扩容
{
	int k = capacity * 1.5;		//每次扩容1.5倍
	datatype* t = (datatype*)realloc(lty, k * sizeof(datatype));
	lty = t;
	capacity = k;
}


void heap::adjustup()			//向上调整
{
	int pos = size - 1;			//pos是最后一个元素的下标
	while (pos > 0)
	{
		if (lty[pos] < lty[(pos - 1) / 2])	//当最后一个元素比它的parent小的时候
		{
			heap::swap(lty[pos], lty[(pos - 1) / 2]);	//交换
		}
		else
		{
			break;
		}
		pos = (pos - 1) / 2;	//每次交换完让pos等于上一次的pos的parent
	}							//然后继续用新的pos与pos的parent比较/交换
}

datatype heap::deletetop()		//删除堆顶元素并返回堆顶元素
{
	datatype re = lty[0];		//记录下堆顶元素的值
	lty[0] = lty[size-1];		//把最后一个元素移到堆顶来
	size--;						//相当于删除了一个元素
	adjustdown();				//把堆顶元素(之前的最后一个)向下调整
	return re;					//返回之前删除的堆顶元素
}


void heap::adjustdown()			//向下调整
{
	int parentpos = 0;			//记录下parent的下标
	int smallchild = parentpos * 2 + 1;		//假设parent的较小孙节点的下标为左孙节点
	while (parentpos*2+1<size)			//parent子节点的下标在size范围内的时候
	{
		if (lty[smallchild] > lty[smallchild + 1])	//如果左孙大于右孙
		{
			smallchild++;		//就让假设的左孙下标变成右孙下标
		}
		if (lty[smallchild] < lty[parentpos])		//如果孙比parent小
		{
			swap(lty[smallchild], lty[parentpos]);	//就让孙和parent交换
			parentpos = smallchild;					//让parent等于刚才的孙
			smallchild = parentpos * 2 + 1;			//假设小孙是parent的左孙
		}
		else
		{
			break;		//如果孙==parent或者孙>parent就跳出while循环
		}
	}
}


datatype* heap::heapsort()			//排个序并返回排序后的数组
{
	datatype * arr = new datatype[size*sizeof(datatype)];	//new一个新的数组
	int sizea = size;					//提前把size记录下来,因为出堆顶数据的时候会size--
	for (int k = 0; k < sizea; k++)		//出堆顶数据的同时把返回的堆顶的值存到arr数组里
	{
		arr[k] = deletetop();
	}
	for (int m = 0; m < sizea; m++)		//查看一下排序之后的数组
	{
		cout << arr[m] << " ";
	}
	cout << endl << endl;
	return arr;				//把排序好的数组返回去
}

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#include"heap.h"

void test()
{
	heap a(8);		//构造一个队 
	a.push(3);		//一直入数据
	a.push(5);
	a.push(11);
	a.push(4);
	a.push(12);
	a.push(21);
	a.push(15);
	a.push(7);
	a.look();		//查看一下堆
	cout << endl << endl;
	cout << a.deletetop() << endl;	//删除堆顶数据看一下
	a.look();		//再看看堆
	cout << a.deletetop() << endl;	//在删除一个
	a.look();		//再看一下
	a.heapsort();	//排个序看一下
}


int main()
{
	test();		//测试函数
	return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值