堆排(一)——用自己的代码实现堆

很激动,竟然有人看我的文章
首先感谢liuyubobobo的代码, 点击打开链接
我决定好好把堆这一块的知识再补充一下

堆的三个要点:
①建堆——从第一个非叶子节点开始,从后往前,将每一个小堆都变成最大堆(这是一个和孩子比较大小的过程,shiftDown)  

②插入堆——这是一个和父节点比较大小的过程(shiftUp)

③pop堆——将当前堆的第一个元素和最后一个元素交换位置,然后对剩下的n-1个重新建堆(shiftDown)



template<typename Item>
class MaxHeap {
private:
	Item* data;    //堆的数组
	int count;      //堆中元素的个数
	int capacity;    //堆的容量

	void shiftUp(int k)
	{
		while (k>1 && data[k / 2] < data[k])
		{
			swap(data[k / 2], data[k]);
			k /= 2;
		}
	}

	void shiftDown(int k)
	{
		while (2 * k <= count)
		{
			int j = 2 * k;
			if (j + 1 <= count&& data[j + 1] > data[j])
				j = j + 1;

			if (data[k] > data[j])
				break;
			//可以优化的点
			swap(data[k], data[j]);
			k = j;
		}
	}

public:
	MaxHeap(int capacity)
	{
		data = new Item[capacity + 1];
		count = 0;
		this->capacity = capacity;
	}

	MaxHeap(Item arr[], int n)
	{   //建堆
		data = new Item[n + 1];
		capacity = n;
		for (int i = 0; i < n; i++)
			data[i + 1] = arr[i];
		count = n;
		for (int i = count / 2; i >= 1; i--)
			shiftDown(i);
	}

	~MaxHeap()
	{
		delete[] data;
	}

	int size()
	{
		return count;
	}

	bool isEmpty()
	{
		return count == 0;
	}

	void insert(Item item)
	{
		assert(count + 1 <= capacity);

		data[count + 1] = item;
		count++;
		shiftUp(count);
	}

	Item extractMax()
	{
		assert(count > 0);
		Item ret = data[1];
		swap(data[1], data[count]);
		count--;
		shiftDown(1);
		return ret;
	}
};

猜你喜欢

转载自blog.csdn.net/eereere/article/details/80305317