C++最大堆实现

max_heap.h

#pragma once
#include <cstdint>

template <class T>
class max_heap {
private:
	struct node {
		uint32_t	size;
		T*			data;
	};

	node*		_heap;		//最大堆
	uint32_t	_max_size;	//最大存储数
	uint32_t	_size;		//存储数

	// 扩容
	void expansion();
	// 删除指定下标节点
	void del_node(uint32_t index_);

protected:
public:
	max_heap(uint32_t max_size_ = 64);
	~max_heap();
	// 首元素
	const node* begin();
	// 末尾元素后一位
	const node* end();
	// 获取最大值
	const node* front();
	// 添加数据
	void push(uint32_t size_, T* data_);
	// 删除最大值
	T* pop();
	// 删除指定值
	T* del(uint32_t size_);
	// 查找指定值
	T* find(uint32_t size_);
	// 是否空
	bool empty();
	// 清空
	void clear();
	// 大小
	uint32_t size();
};

#include "max_heap.tcc"

max_heap.tcc

template <class T>
max_heap<T>::max_heap(uint32_t max_size_) :
	_heap(new node[max_size_]{}),
	_max_size(max_size_),
	_size(0)
{}

template <class T>
max_heap<T>::~max_heap() {
	delete[] _heap;
}

template <class T>
void max_heap<T>::expansion() {
	auto size = sizeof(node) * _max_size;
	node* new_heap = new node[_max_size <<= 1]{};
	memcpy_s(new_heap, size << 1, _heap, size);
	delete[] _heap;
	_heap = new_heap;
}

template <class T>
void max_heap<T>::del_node(uint32_t index_) {
	if (_size < index_) {
		return;
	}
	// 向下调整
	if (_heap[_size].size < _heap[index_].size) {
		uint32_t index1 = index_, index2 = index1 << 1;
		while (index2 < _size) {
			if (_heap[index2].size < _heap[index2 + 1].size) {
				++index2;
			}
			if (_heap[_size].size < _heap[index2].size) {
				_heap[index1] = _heap[index2];
				index1 = index2;
				index2 <<= 1;
			}
			else {
				break;
			}
		}
		_heap[index1] = _heap[_size];
		memset(&_heap[_size], 0, sizeof(node));
	}
	// 向上调整
	else if (_heap[_size].size > _heap[index_].size) {
		uint32_t index1 = index_ >> 1, index2 = _size;
		while (_heap[index1].size < _heap[index2].size) {
			std::swap(_heap[index1], _heap[_size]);
			index2 = index1;
			index1 >>= 1;
		}
		_heap[index_] = _heap[_size];
		memset(&_heap[_size], 0, sizeof(node));
	}
	// 不做调整
	else {
		_heap[index_] = _heap[_size];
		memset(&_heap[_size], 0, sizeof(node));
	}
	_size -= 1;
}

template <class T>
inline const typename max_heap<T>::node* max_heap<T>::begin() {
	return _heap + 1;
}

template <class T>
inline const typename max_heap<T>::node* max_heap<T>::end() {
	return _heap + _size + 1;
}

template <class T>
inline const typename max_heap<T>::node* max_heap<T>::front() {
	if (_size < 1) {
		return nullptr;
	}
	return _heap + 1;
}

template <class T>
void max_heap<T>::push(uint32_t size_, T* data_) {
	if (!data_) {
		return;
	}
	if (++_size == _max_size) {
		expansion();
	}
	_heap[_size].size = size_;
	_heap[_size].data = data_;
	uint32_t index1 = _size, index2 = index1 >> 1;
	while (index1 > 1 && _heap[index2].size < _heap[index1].size) {
		std::swap(_heap[index1], _heap[index2]);
		index1 = index2;
		index2 >>= 1;
	}
}

template <class T>
inline T* max_heap<T>::pop() {
	if (_size < 1) {
		return nullptr;
	}
	T* data = _heap[1].data;
	del_node(1);
	return data;
}

template <class T>
T* max_heap<T>::del(uint32_t size_) {
	if (_size < 1) {
		return nullptr;
	}
	// push了key值相同的复数数据可能不是想要的结果
	uint32_t index1 = 0;
	for (uint32_t i = 1; i <= _size; ++i) {
		if (_heap[i].size == size_) {
			index1 = i;
			break;
		}
	}
	if (index1) {
		T* data = _heap[index1].data;
		del_node(index1);
		return data;
	}
	return nullptr;
}

template <class T>
T* max_heap<T>::find(uint32_t size_) {
	uint32_t index1 = 0;
	for (uint32_t i = 1; i <= _size; ++i) {
		if (_heap[i].size == size_) {
			index1 = i;
			break;
		}
	}
	if (!index1) {
		return nullptr;
	}
	return _heap[index1].data;
}

template <class T>
inline bool max_heap<T>::empty() {
	return _size == 0;
}

template <class T>
inline void max_heap<T>::clear() {
	while (!empty()) {
		pop();
	}
}

template <class T>
inline uint32_t max_heap<T>::size() {
	return _size;
}

备注:如果是push降序数据的话比push升序数据快得多。

可以使用for(auto& i : xxx)语法进行遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过下面的代码实现最小最大堆: ```c #include <stdio.h> #include <stdlib.h> #define MAX_HEAP_SIZE 100 typedef struct Heap { int* data; int size; } Heap; Heap* create_heap() { Heap* heap = (Heap*)malloc(sizeof(Heap)); heap->data = (int*)malloc(sizeof(int) * MAX_HEAP_SIZE); heap->size = 0; return heap; } void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } void down_adjust(Heap* heap, int index, int is_min_heap) { int left = index * 2 + 1; int right = index * 2 + 2; int maxmin = index; if (is_min_heap) { if (left < heap->size && heap->data[left] < heap->data[maxmin]) maxmin = left; if (right < heap->size && heap->data[right] < heap->data[maxmin]) maxmin = right; } else { if (left < heap->size && heap->data[left] > heap->data[maxmin]) maxmin = left; if (right < heap->size && heap->data[right] > heap->data[maxmin]) maxmin = right; } if (maxmin != index) { swap(&heap->data[maxmin], &heap->data[index]); down_adjust(heap, maxmin, is_min_heap); } } void up_adjust(Heap* heap, int index, int is_min_heap) { if (index == 0) return; int parent = (index - 1) / 2; if (is_min_heap) { if (heap->data[index] < heap->data[parent]) { swap(&heap->data[index], &heap->data[parent]); up_adjust(heap, parent, is_min_heap); } } else { if (heap->data[index] > heap->data[parent]) { swap(&heap->data[index], &heap->data[parent]); up_adjust(heap, parent, is_min_heap); } } } void insert(Heap* heap, int value, int is_min_heap) { if (heap->size == MAX_HEAP_SIZE) { printf("Heap is full!\n"); return; } heap->data[heap->size] = value; heap->size++; up_adjust(heap, heap->size - 1, is_min_heap); } void remove_heap(Heap* heap, int value, int is_min_heap) { if (heap->size == 0) { printf("Heap is empty!\n"); return; } int i; for (i = 0; i < heap->size; i++) { if (heap->data[i] == value) break; } if (i == heap->size) { printf("Element not found in heap!\n"); return; } heap->data[i] = heap->data[heap->size - 1]; heap->size--; down_adjust(heap, i, is_min_heap); } void print_heap(Heap* heap) { int i; for (i = 0; i < heap->size; i++) printf("%d ", heap->data[i]); printf("\n"); } int main() { Heap* min_heap = create_heap(); Heap* max_heap = create_heap(); insert(min_heap, 5, 1); insert(min_heap, 6, 1); insert(min_heap, 4, 1); insert(min_heap, 2, 1); insert(min_heap, 3, 1); insert(max_heap, 5, 0); insert(max_heap, 6, 0); insert(max_heap, 4, 0); insert(max_heap, 2, 0); insert(max_heap, 3, 0); printf("Min heap: "); print_heap(min_heap); printf("Max heap: "); print_heap(max_heap); remove_heap(min_heap, 4, 1); remove_heap(max_heap, 4, 0); printf("Min heap after removing 4: "); print_heap(min_heap); printf("Max heap after removing 4: "); print_heap(max_heap); return 0; } ``` 这段代码实现了最小最大堆的基本功能,包括创建堆、插入元素、删除元素和打印堆。其中,指定 is_min_heap 参数可以创建最小堆或最大堆。注意,在删除元素时,需要先将要删除的元素与堆的最后一个元素交换位置,然后再进行下沉操作,以保证堆的完整性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值