最大堆

// Binary Heap
#include <iostream>
#include <cassert>
#include <string>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <typeinfo>
using namespace std;

template<typename Item>
class MaxHeap {
	
	private :
		Item * data;
		int count;
		int capacity;
		
		void putNumberInLine( int num, string &line, int index_cur_level, int cur_tree_width, bool isLeft){
	
	        int sub_tree_width = (cur_tree_width - 1) / 2;
	        int offset = index_cur_level * (cur_tree_width+1) + sub_tree_width;
	        assert(offset + 1 < line.size());
	        if( num >= 10 ) {
	            line[offset + 0] = '0' + num / 10;
	            line[offset + 1] = '0' + num % 10;
	        }
	        else{
	            if( isLeft)
	                line[offset + 0] = '0' + num;
	            else
	                line[offset + 1] = '0' + num;
	        }
	    }
	
	    void putBranchInLine( string &line, int index_cur_level, int cur_tree_width){
	
	        int sub_tree_width = (cur_tree_width - 1) / 2;
	        int sub_sub_tree_width = (sub_tree_width - 1) / 2;
	        int offset_left = index_cur_level * (cur_tree_width+1) + sub_sub_tree_width;
	        assert( offset_left + 1 < line.size() );
	        int offset_right = index_cur_level * (cur_tree_width+1) + sub_tree_width + 1 + sub_sub_tree_width;
	        assert( offset_right < line.size() );
	
	        line[offset_left + 1] = '/';
	        line[offset_right + 0] = '\\';
	    }
		
		void shiftUp(int k) {
			
			while(k > 1 && data[k / 2] < data[k]) {
				swap(data[k / 2], data[k]);
				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[j], data[k]);
				k = j;	// k下放 
			}
		}
	
	public :
		MaxHeap(int capacity) {
			data = new Item[capacity + 1];
			count = 0;
			this->capacity = capacity;
		}
		
		~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 testPrint(){

	        // 我们的testPrint只能打印100个元素以内的堆的树状信息
	        if( size() >= 100 ){
	            cout<<"This print function can only work for less than 100 int";
	            return;
	        }
	
	        // 我们的testPrint只能处理整数信息
	        if( typeid(Item) != typeid(int) ){
	            cout <<"This print function can only work for int item";
	            return;
	        }
	
	        cout<<"The max heap size is: "<<size()<<endl;
	        cout<<"Data in the max heap: ";
	        for( int i = 1 ; i <= size() ; i ++ ){
	            // 我们的testPrint要求堆中的所有整数在[0, 100)的范围内
	            assert( data[i] >= 0 && data[i] < 100 );
	            cout<<data[i]<<" ";
	        }
	        cout<<endl;
	        cout<<endl;
	
	        int n = size();
	        int max_level = 0;
	        int number_per_level = 1;
	        while( n > 0 ) {
	            max_level += 1;
	            n -= number_per_level;
	            number_per_level *= 2;
	        }
	
	        int max_level_number = int(pow(2, max_level-1));
	        int cur_tree_max_level_number = max_level_number;
	        int index = 1;
	        for( int level = 0 ; level < max_level ; level ++ ){
	            string line1 = string(max_level_number*3-1, ' ');
	
	            int cur_level_number = min(count-int(pow(2,level))+1,int(pow(2,level)));
	            bool isLeft = true;
	            for( int index_cur_level = 0 ; index_cur_level < cur_level_number ; index ++ , index_cur_level ++ ){
	                putNumberInLine( data[index] , line1 , index_cur_level , cur_tree_max_level_number*3-1 , isLeft );
	                isLeft = !isLeft;
	            }
	            cout<<line1<<endl;
	
	            if( level == max_level - 1 )
	                break;
	
	            string line2 = string(max_level_number*3-1, ' ');
	            for( int index_cur_level = 0 ; index_cur_level < cur_level_number ; index_cur_level ++ )
	                putBranchInLine( line2 , index_cur_level , cur_tree_max_level_number*3-1 );
	            cout<<line2<<endl;
	
	            cur_tree_max_level_number /= 2;
        }
	}
};

int main()
{
	MaxHeap<int> maxheap = MaxHeap<int>(100);
	//cout << maxheap.size() << endl;
	
	srand(time(NULL));
	for(int i = 0; i < 15; ++ i) {
		maxheap.insert(rand() % 100);
	}
	
	while(!maxheap.isEmpty())
		cout << maxheap.extractMax() << " ";
	cout << endl;
	
	return 0;
}

  

posted @ 2019-03-25 20:32  青衫客36  阅读(166)  评论(0编辑  收藏  举报