1. 程式人生 > >堆排(一)——用自己的程式碼實現堆

堆排(一)——用自己的程式碼實現堆

很激動,竟然有人看我的文章首先感謝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;
	}
};