c++ 手写堆 (包括建堆排序添加元素删除元素)

Posted 每天告诉自己要努力

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ 手写堆 (包括建堆排序添加元素删除元素)相关的知识,希望对你有一定的参考价值。

快排和归并排序点这里
c++进阶之路
堆排序跟快排一样是原地操作的一种不稳定排序算法。
堆排序分为建堆和调整堆。

建堆是通过自底向上父节点和子节点两两比较并交换得到的,时间复杂度为O(n)

调整堆需要交换n-1次堆顶元素,并调整堆,调整堆的过程就是满二叉树的深度logn,所以时间复杂度为O(nlogn),所以最终时间复杂度为O(nlogn)。

每次都是只操作一个数据,没有额外的辅助空间,空间复杂度为O(1)。

添加元素,需要添加到最后面,也就是最右边的叶子节点,然后自下而上进行调整,直到son < parent,这个时间复杂度最大是O(logn);

删除元素,因为是要删除堆顶元素,这里的做法是把末尾元素和根元素交换,并且把已经换到末尾的根元素从容器中删掉,然后再调整新的根节点。
也就是hepify(0);

#include <iostream>
#include <vector>
using namespace std;


class myHeap 
public:
	int size()  return nums.size(); 
	vector<int> nums;
	int top() 
		if (nums.size() == 0) return -1;
		return nums[0];
	
	bool empty() 
		return size() == 0 ? true : false;
	
	myHeap() 
		
	

	void heapSort() 
		int lastIndex = size() - 1;

		for (int i = lastIndex; i >= 0; i--) 
			swap(nums[0], nums[i]);
			heapify(nums, i, 0);
		
	

	void del() 
		if (nums.size() == 0) return;
		int lastIndex = nums.size() - 1;
		swap(nums[0], nums[lastIndex]); //把根节点和最右的叶子互换
		nums.pop_back();//然后heapsize - 1
		heapify(nums, nums.size(), 0);//再调整最右的叶子
	


	void add(int num) 
		nums.push_back(num);
		int son = nums.size() - 1;
		int parent = (son - 1) / 2;
		while (parent >= 0 && nums[son] > nums[parent]) 
			swap(nums[son], nums[parent]);
			son = parent;
			parent = (son - 1) / 2;
		
	
	void print() 
		for (auto x : nums) cout << x << " ";
		cout << endl;
	
private:
	void heapify(vector<int>& nums, int len, int i) 
		int l = i * 2 + 1, r = i * 2 + 2;
		int max = i;
		if (l < len && nums[max] < nums[l]) max = l;
		if (r < len && nums[max] < nums[r]) max = r;
		if (max != i) 
			swap(nums[max], nums[i]);
			heapify(nums, len, max);
		
	
	void buildHeap(vector<int>& nums, int len) 
		int lastIndex = len - 1;
		int lastParent = (lastIndex - 1) / 2;
		for (int i = lastParent; i >= 0; i--) 
			heapify(nums, len, i);
		
	
;


int main() 
	
	myHeap heap;
	cout << heap.empty() << endl;
	cout << heap.size() << endl;
	cout << heap.top() << endl;

	heap.add(5); 
	heap.del();
	heap.heapSort();
	heap.print();

	return 0;

以上是关于c++ 手写堆 (包括建堆排序添加元素删除元素)的主要内容,如果未能解决你的问题,请参考以下文章

排序算法总结之堆排序

c++堆排序

自建堆排序:

20191209-八大排序之堆排序

建堆,以及对堆排序

堆排序