堆之大頂堆實現和操做

#include <iostream>
#include <cassert>
#include <ctime>
using namespace std;
/**
一句箴言: 堆老是一棵徹底二叉樹,堆中某一節點的值老是不大於其父節點的值, 插入節點使用shiftUp,取出最大值(根節點)後須要使用 shiftDown向下整理

方法: 變更後使用遞歸或者循環的方式,按照堆的定義進行值的互換調整便可

**/
template<typename Item>
class MaxHeap {
	private:
		Item* data;
		int count;
		int capacity;
//從堆中取出第一個元素後,用最後一個元素替換後,自頂向下進行調整
		void shiftDown(int k) {
			while(2*k <= count) {
				int j = 2*k;
				if (j + 1 <= count && data[j+1] > data[j]) {
					j+=1;
				}
				if (data[k] >= data[j]) {
					break;
				}
				swap(data[k], data[j]);
				k=j;
			}
			/**
			//下面爲遞歸寫法
			if (2 * k > count) {
				return;
			}
			int j = 2*k;
			if (j+1 <=count && data[j] < data[j+1]) {
				j = j+1;
			}
			swap(data[k], data[j]);
			shiftDown(j);
			**/
		}

//		從堆最後插入元素後進行自底向上調整
		void shiftUp(int k) {
			while(k > 1 && data[k/2] < data[k]) {
				swap(data[k/2], data[k]);
				k = k/2;
			}

			/**
			//下面爲遞歸寫法
			if (k > 1 && data[k/2] < data[k]) {
				swap(data[k/2] , data[k]);
				k = k/2;
				shiftUp(k);
			}
			**/
		}

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

		~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;
		}
		void printData() {
			for(int i =1; i<=count; i++) {
				cout<<data[i] <<  " ";
			}
		}

};


int main() {

	MaxHeap<int> maxheap = MaxHeap<int>(100);
	srand(time(NULL));
	for (int i =0; i<5; i++) {
		int  tmp = rand()%10;
		maxheap.insert(tmp);
		cout<<tmp <<  " ";
	}
	cout<<endl;
	maxheap.printData();

	maxheap.extractMax();
	cout<<endl;
	maxheap.printData();

	maxheap.extractMax();
	cout<<endl;
	maxheap.printData();

	return 0;
}
相關文章
相關標籤/搜索