Heap(堆)的C++实现

本文详细介绍了堆排序的基本操作,包括上浮、下沉、输出最大值/最小值、插入节点、删除节点以及建立堆的过程。通过示例代码展示了如何使用C++实现一个通用的堆排序模板类,并在main函数中进行了实际操作,将随机生成的数据进行堆排序展示。

Heap的实现主要有下面几个函数构成。

  • swim  上浮动
  • sink    下浮动
  • top     输出最大值/最小值(根节点)
  • push  堆中增加节点
  • pop    删除根部节点
  • build   建立堆结构
typedef int DTYPE;

DTYPE heap[M_SIZE];
int heap_size = 0;

void swap(DTYPE& a, DTYPE& b) {
	DTYPE temp = a;
	a = b;
	b = temp;
}

void swimNode(int index) {
	for (int s_idx = index; s_idx > 1 && heap[s_idx] > heap[s_idx / 2]; s_idx /= 2) {
		swap(heap[s_idx], heap[s_idx / 2]);
	}
}

int sonNode(int index) {
	return 2 * index + (2 * index + 1 <= heap_size && heap[2 * index + 1] > heap[2 * index]);
}
void sinkNode(int index) {
	for (int f_idx = index, s_idx = sonNode(f_idx); s_idx <= heap_size && heap[s_idx] > heap[f_idx]; f_idx = s_idx, s_idx = sonNode(f_idx)) {
		swap(heap[f_idx], heap[s_idx]);
	 }
}

void push(DTYPE data) {
	heap[++heap_size] = data;
	swimNode(heap_size);
}

void pop() {
	swap(heap[1], heap[heap_size--]);
	sinkNode(1);
}

DTYPE top() {
	return heap[1];
}

void build(DTYPE data[], int a) {
	memcpy(heap + 1, data, sizeof(DTYPE) * a);
	heap_size = a;
	for (int i = a / 2; i > 0; i--) {
		sinkNode(i);
	}
}

通过class进行封装,可以参考下述 

typedef int DTYPE;
#define M_SIZE 20

template<typename Type>
class HeapSort {
public:
	HeapSort(const int capacity) : heap_(nullptr), capacity_(capacity), heap_size_(0) {}
	~HeapSort() {
		delete[] heap_;
		capacity_ = 0;
		heap_size_ = 0;
	}
	void push(const Type& data) {
		if (heap_size_ == capacity_) {
			throw "Over heap size, check.";
		}
		heap_[++heap_size_] = data;
		swimNode(heap_size_);
	}
	void pop() {
		swap(heap_[1], heap_[heap_size_--]);
		sinkNode(1);
	}
	Type top() const {
		return heap_[1];
	}
	int size() const {
		return heap_size_;
	}
	void build(Type data[], int a) {
		heap_ = new Type[a];
		memcpy(heap_ + 1, data, sizeof(Type) * a);
		heap_size_ = a;
		for (int i = a / 2; i > 0; i--) {
			sinkNode(i);
		}
	}
private:
	int capacity_;
	int heap_size_ = 0;
	Type* heap_;

	void swap(Type& a, Type& b) {
		Type temp = a;
		a = b;
		b = temp;
	}
	void swimNode(const int index) {
		for (int s_idx = index; s_idx > 1 && heap_[s_idx] > heap_[s_idx / 2]; s_idx /= 2) {
			swap(heap_[s_idx], heap_[s_idx / 2]);
		}
	}
	int sonNode(const int index) {
		return 2 * index + (2 * index + 1 <= heap_size_ && heap_[2 * index + 1] > heap_[2 * index]);
	}
	void sinkNode(const int index) {
		for (int f_idx = index, s_idx = sonNode(f_idx); s_idx <= heap_size_ && heap_[s_idx] > heap_[f_idx]; f_idx = s_idx, s_idx = sonNode(f_idx)) {
			swap(heap_[f_idx], heap_[s_idx]);
		}
	}
};


int main() {
	DTYPE data[20];

	//srand((int)(time(NULL)));
	for (int i = 0; i < 15; i++) {
		data[i] = 0 + rand() % 100;
		cout << 0 + rand() % 100 << endl;;
	}

	HeapSort<DTYPE> heapSort = HeapSort<DTYPE>(20);
	heapSort.build(data, 15);

	cout << "Big root heap:  " << endl;

	heapSort.push(232);
	heapSort.push(90);
	heapSort.push(54);
	heapSort.push(232);
	heapSort.push(90);

	auto size = heapSort.size();
	for (int i = 0; i < size; i++) {
		cout << heapSort.top() << endl;
		heapSort.pop();
		cout << "size: " << heapSort.size() << endl;
	}
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值