zoukankan      html  css  js  c++  java
  • 堆的建立与功能实现

    今天忽然意识到一个问题..考试的代码是手写...糟糕了以我的英语水平根本就不能取太复杂的变量名啊

    • 代码
    #define defaultsize 10
    #include<iostream>
    using namespace std;
    
    template<class T>
    class MinHeap
    {
    public:
    	MinHeap(int sz =defaultsize);           //建立空堆,再利用Insert函数一个一个加入形成最小堆
    	MinHeap(T arr[], int n);      //传入数组,直接建立最小堆
    	~MinHeap() { delete[]heap; }
    	bool Insert( T x);      //将x插入最小堆中
    	bool Remove(T& x);            //将最小堆顶部元素(最小元素)删除,用x返回
    	bool IsEmpty()
    	{
    		return (currentSize == 0) ? true:false;
    	}
    	bool IsFull()
    	{
    		return (currentSize == maxHeapSize) ? true : false;
    	}
    private: 
    	T* heap;           //堆是用数组储存的!
    	int currentSize;   //目前堆中元素个数
    	int maxHeapSize;   //堆中允许最多元素个数
    	void siftDown(int start, int end);         //从start到end自上到下形成最小堆//建立堆,删除元素
    	void siftUp(int start);                    //从start到自下玩上形成最小堆//增添元素
    };
    
    template <class T>                            //第一种构造方式
    MinHeap<T>::MinHeap(int sz)
    {
    	maxHeapSize = (defaultsize < sz) ? sz : defaultsize;
    	heap = new T[maxHeapSize];
    	currentSize = 0;
    }
    
    template<class T>
    MinHeap<T>::MinHeap(T arr[], int n)
    {
    	maxHeapSize = (defaultsize < n) ? n : defaultsize;
    	heap = new T[maxHeapSize];
    	for (int i = 0;i <= n - 1;i++) heap[i] = arr[i];
    	currentSize = n;
    	int p = (currentSize - 2) / 2;          //最后一个分支结点的下标
    	while (p >= 0)
    	{
    		siftDown(p, currentSize - 1);
    		p--;
    	}
    }
    
    template <class T>
    void MinHeap<T>::siftDown(int start, int end)
    {
    	int i = start,j = 2 * i + 1;
    	T temp = heap[i];                       //暂存heap[i]的值
    	while (j <= end)                          //i有分支
    	{
    		if (j<end && heap[j]>heap[j + 1])j++; //如果i有两个分支 j指向较小的那一个分支 
    		if (temp <= heap[j])break;
    		else
    		{
    			heap[i] = heap[j];
    			i = j;
    			j = 2 * j + 1;
    		}
    	}
    	heap[i] = temp;                       //放入
    }
    
    template <class T>
    void MinHeap<T>::siftUp(int start)
    {
    	int j = start, i = (j - 1) / 2;
    	T temp = heap[j];
    	while (j > 0)
    	{
    		if (temp >= heap[i])break;        //默认上面已经是排好序的
    		else
    		{
    			heap[j] = heap[i];
    			j = i;
    			i = (j - 1) / 2;
    		}
    	}
    	heap[j] = temp;                      //送回
    }
    
    template <class T>
    bool MinHeap<T>::Insert( T x)
    {
    	if (IsFull())
    	{
    		cout << "Heap Full" << endl;
    		return false;
    	}
    	else
    	{
    		heap[currentSize] = x;
    		siftUp(currentSize);
    		currentSize++;
    		return true;
    	}
    }
    template<class T>
    bool MinHeap<T>::Remove(T& x)
    {
    	if (IsEmpty())
    	{
    		cout << "Heap Empty " << endl;
    		return false;
    	}
    	else
    	{
    		x = heap[0];
    		heap[0] = heap[currentSize - 1];    //最后一个元素补过去
    		currentSize--;
    		siftDown(0, currentSize - 1);
    		return true;
    	}
    }
    
    int main()
    {
    	int x;
    	MinHeap<int> h1;
    	h1.Insert(53);
    	h1.Insert(17);
    	h1.Insert(78);
    	h1.Insert(9);
    	h1.Insert(45);
    	h1.Insert(65);
    	h1.Insert(87);
    	h1.Insert(23);
    	int a[8] = { 53,17,78,9,45,65,87,23 };
    	MinHeap<int >h2(a, 8);
    	cout << "MinHeap h1:";
    	for (int i = 1;i <= 8;i++)
    	{
    		h1.Remove(x);
    		cout << x << " ";
    	}
    	cout << endl;
    	cout << "MinHeap h2:";
    	for (int i = 1;i <= 8;i++)
    	{
    		h2.Remove(x);
    		cout << x << " ";
    	}
    }
    

    堆h1是先建立空堆,再利用insert一个一个插进去,每次插入后都是一个最小堆。
    堆h2是直接传入数组,调整为最小堆。

  • 相关阅读:
    nyoj 游戏高手的烦恼 (二分图最小点覆盖)
    nyoj 三国志 (Dijkstra + 01背包)
    《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅱ
    《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅰ
    Java学习作业(14.4.21)
    2014上年度学习计划
    快速求幂(Quick Exponentiation)
    B. Inna and Nine
    B. Valera and Contest
    Problem 2128 最长子串
  • 原文地址:https://www.cnblogs.com/yuuuuu422/p/13211277.html
Copyright © 2011-2022 走看看