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++ 手写堆 (包括建堆排序添加元素删除元素)的主要内容,如果未能解决你的问题,请参考以下文章