温故而知新 -> 数据结构 -> 二叉树 -> 顺序存储 ->程序实现2_利用类
本篇博客是基于 温故而知新 -> 数据结构 ->树 -> 二叉树 -> 顺序存储 中实现堆顺序存储 的理论知识进行程序实现!
其中实现了 堆 的 增(入堆)删(出堆)查(堆顶元素)改(没写(~ ̄▽ ̄)~),判空,打印等操作!并附带了相关实例以及对应的运行结果!
注意:其中代码有很大冗余,且未考虑性能最优,读者有兴趣可进一步精简!
具体内容如下
(1)Heap.h
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
typedef int HDataType;
// 向上调整 小堆 -- 插入
void ShiftUp(HDataType *arr, int n, int pos)// pos 为输入节点的位置
{
//获取父节点位置
int parent = (pos - 1) / 2;
while (pos > 0)
{
//比较当前位置和父节点,谁小谁上
if (arr[pos] < arr[parent])
{
int tmp = arr[parent];
arr[parent] = arr[pos];
arr[pos] = tmp;
//交换结束后,更换位置,继续往上走
pos = parent;
parent = (pos - 1) / 2;
}
else
break;//结束调整
}
}
// 向下调整 小堆 -- 删除
void ShiftDown(HDataType *arr, int n, int pos)
{
int child = 2 * pos + 1;//左孩子
while (child < n)
{
//从左右孩子中找到一个最小值的位置
if (((child + 1) < n) && (arr[child + 1] < arr[child]))
++child;//和右孩子进行交换
//需要调整的数据和最小值进行比较,若小于最小值,则不需要交换,反之需要交换
if (arr[child] < arr[pos])
{
int tmp = arr[pos];
arr[pos] = arr[child];
arr[child] = tmp;
//更新当前位置
pos = child;
child = 2 * pos + 1;
}
else
break;
}
}
向下调整 大堆 -- 删除
//void shiftDown(int *arr, int n, int pos)
//{
// //printf("%d ", arr[1]);
// //左孩子
// int child = 2 * pos + 1;
// while (child < n)
// {
// //从左右孩子中找到一个最小值的位置
// if (((child + 1) < n) && (arr[child + 1] > arr[child]))
// ++child;//和右孩子进行交换
// //需要调整的数据和最小值进行比较,若小于最小值,则不需要交换,反之需要交换
// if (arr[child] > arr[pos])
// {
// int t = arr[pos];
// arr[pos] = arr[child];
// arr[child] = t;
//
// //更新当前位置
// pos = child;
// child = 2 * pos + 1;
// }
// else
// break;
// }
//
//}
class Heap
{
public:
Heap()
:_data(nullptr)
, _size(0)
, _capa(0)
{}
// 判空
bool HeapEmpty();
// 检测容量
void CheakCapacity();
// 插入
void HeapPush(HDataType val);
// 删除
void HeapPop();
// 获取栈顶元素
HDataType HeapTop();
// 打印
void HeapPrint();
private:
HDataType *_data;
int _size;
int _capa;
};
(2)main.cpp
#include"Heap.h"
void Swap(HDataType *a, HDataType *b)
{
HDataType tmp = *a;
*a = *b;
*b = tmp;
}
// 判空
bool Heap::HeapEmpty()
{
if (_size == 0)
return true;
else
return false;
}
// 检测容量
void Heap::CheakCapacity()
{
if (_size == _capa)
{
_capa = _capa == 0 ? 1 : 2 * _capa;
_data = (HDataType*)realloc(_data,_capa*sizeof(HDataType));
}
}
// 插入
void Heap::HeapPush(HDataType val)
{
//检查容量
Heap::CheakCapacity();
//尾插
_data[_size++] = val;
//向上调整,从最后一个位置开始往上,从0开始计数
ShiftUp(_data, _size, _size - 1);
}
// 删除
void Heap::HeapPop()
{
assert(_size != 0);
//首尾交换,然后向下调整
Swap(&_data[0], &_data[_size - 1]);
_size--;
ShiftDown(_data, _size, 0);
}
// 获取栈顶元素
HDataType Heap::HeapTop()
{
return _data[0];
}
// 打印
void Heap::HeapPrint()
{
cout << "堆中内容:";
for (int i = 0; i < _size; i++)
cout << _data[i] << " ";
cout << endl;
}
void test()
{
Heap hp;
/* 实验堆的插入 */
hp.HeapPush(66);
hp.HeapPrint();// 66
hp.HeapPush(55);
hp.HeapPrint();// 55 66
hp.HeapPush(22);
hp.HeapPrint();// 22 66 55
hp.HeapPush(44);
hp.HeapPrint();// 22 44 55 66
hp.HeapPush(33);
hp.HeapPrint();// 22 33 55 66 44
hp.HeapPush(11);
hp.HeapPrint();// 11 33 22 66 44 55
/* 实验堆的删除 */
hp.HeapPop();
hp.HeapPrint();// 22 33 55 66 44
hp.HeapPop();
hp.HeapPrint();// 33 44 55 66
hp.HeapPop();
hp.HeapPrint();// 44 66 55
hp.HeapPop();
hp.HeapPrint();// 55 66
/* 实验栈顶 */
cout << "此时堆顶元素为:" << hp.HeapTop() << endl;
}
int main()
{
test();
system("pause");
return 0;
}
(3)运行结果
注意:其实在上述程序中完全可以用模板去代替实现数据类型的设定,但因为这两功能差不多,且只是为了简单说明,所以没用模板,而用的是 typedef
!
以上就是本篇博客内容!
侵权删~