堆排序

// test heap sort <pre name="code" class="cpp">//heapSort.cpp

#include <iostream>#include <algorithm>#include "heapSort.h"using namespace std;int main(void){ int a[11], i, n = 10; // initialize descending data for (i = 1; i <= 10; i++) a[i] = n - i + 1; heapSort(a, 10); // output sorted data copy(a, a+n, ostream_iterator<int>(cout, " ")); cout << endl; return 0;}



// heap sort a[1:n]
#ifndef heapSort_
#define heapSort_

#include "maxHeap.h"

using namespace std;

template <class T>
void heapSort(T a[], int n)
{// Sort a[1:n] using the heap sort method.
   // create a max heap of the elements
   maxHeap<T> heap(1);
   heap.initialize(a, n);

   // extract one by one from the max heap
   for (int i = n - 1; i >= 1; i--)
   {
      T x = heap.top();
      heap.pop();
      a[i+1] = x;
   }

   // save array a from heap destructor
   heap.deactivateArray();
}

#endif


maxHeap.h

// heap implementation of a max priority queue
// derives from the ADT maxPriorityQueue

#ifndef maxHeap_
#define maxHeap_

#include "maxPriorityQueue.h"
#include "myExceptions.h"
#include "changeLength1D.h"
#include <sstream>
#include <algorithm>

using namespace std;

template<class T>
class maxHeap : public maxPriorityQueue<T>
{
   public:
      maxHeap(int initialCapacity = 10);
      ~maxHeap() {delete [] heap;}
      bool empty() const {return heapSize == 0;}
      int size() const
          {return heapSize;}
      const T& top()
         {// return max element
            if (heapSize == 0)
               throw queueEmpty();
            return heap[1];
         }
      void pop();
      void push(const T&);
      void initialize(T *, int);
      void deactivateArray()
         {heap = NULL; arrayLength = heapSize = 0;}
      void output(ostream& out) const;
   private:
      int heapSize;       // number of elements in queue
      int arrayLength;    // queue capacity + 1
      T *heap;            // element array
};

template<class T>
maxHeap<T>::maxHeap(int initialCapacity)
{// Constructor.
   if (initialCapacity < 1)
   {ostringstream s;
    s << "Initial capacity = " << initialCapacity << " Must be > 0";
    throw illegalParameterValue(s.str());
   }
   arrayLength = initialCapacity + 1;
   heap = new T[arrayLength];
   heapSize = 0;
}

template<class T>
void maxHeap<T>::push(const T& theElement)
{// Add theElement to heap.

   // increase array length if necessary
   if (heapSize == arrayLength - 1)
   {// double array length
      changeLength1D(heap, arrayLength, 2 * arrayLength);
      arrayLength *= 2;
   }

   // find place for theElement
   // currentNode starts at new leaf and moves up tree
   int currentNode = ++heapSize;
   while (currentNode != 1 && heap[currentNode / 2] < theElement)
   {
      // cannot put theElement in heap[currentNode]
      heap[currentNode] = heap[currentNode / 2]; // move element down
      currentNode /= 2;                          // move to parent
   }

   heap[currentNode] = theElement;
}

template<class T>
void maxHeap<T>::pop()
{// Remove max element.
   // if heap is empty return null
   if (heapSize == 0)   // heap empty
      throw queueEmpty();

   // Delete max element
   heap[1].~T();

   // Remove last element and reheapify
   T lastElement = heap[heapSize--];

   // find place for lastElement starting at root
   int currentNode = 1,
       child = 2;     // child of currentNode
   while (child <= heapSize)
   {
      // heap[child] should be larger child of currentNode
      if (child < heapSize && heap[child] < heap[child + 1])
         child++;

      // can we put lastElement in heap[currentNode]?
      if (lastElement >= heap[child])
         break;   // yes

      // no
      heap[currentNode] = heap[child]; // move child up
      currentNode = child;             // move down a level
      child *= 2;
   }
   heap[currentNode] = lastElement;
}

template<class T>
void maxHeap<T>::initialize(T *theHeap, int theSize)
{// Initialize max heap to element array theHeap[1:theSize].
   delete [] heap;
   heap = theHeap;
   heapSize = theSize;

   // heapify
   for (int root = heapSize / 2; root >= 1; root--)
   {
      T rootElement = heap[root];

      // find place to put rootElement
      int child = 2 * root; // parent of child is target
                            // location for rootElement
      while (child <= heapSize)
      {
         // heap[child] should be larger sibling
         if (child < heapSize && heap[child] < heap[child + 1])
            child++;

         // can we put rootElement in heap[child/2]?
         if (rootElement >= heap[child])
            break;  // yes

         // no
         heap[child / 2] = heap[child]; // move child up
         child *= 2;                    // move down a level
      }
      heap[child / 2] = rootElement;
   }
}

template<class T>
void maxHeap<T>::output(ostream& out) const
{// Put the list into the stream out.
   copy(heap + 1, heap + heapSize + 1, ostream_iterator<T>(cout, "  "));
}

// overload <<
template <class T>
ostream& operator<<(ostream& out, const maxHeap<T>& x)
   {x.output(out); return out;}

#endif



maxPriorityQueue.h

// abstract class max priority queue
// all methods are pure virtual functions

#ifndef maxPriorityQueue_
#define maxPriorityQueue_

using namespace std;

template<class T>
class maxPriorityQueue 
{
   public:
      virtual ~maxPriorityQueue() {}
      virtual bool empty() const = 0;
                  // return true iff queue is empty
      virtual int size() const = 0;
                  // return number of elements in queue
      virtual const T& top() = 0;
                  // return reference to the max element
      virtual void pop() = 0;
                  // remove the top element
      virtual void push(const T& theElement) = 0;
                  // add theElement to the queue
};
#endif


myExceptions.h

// exception classes for various error types

#ifndef myExceptions_
#define myExceptions_
#include <string>

using namespace std;

// illegal parameter value
class illegalParameterValue 
{
   public:
      illegalParameterValue(string theMessage = "Illegal parameter value")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal input data
class illegalInputData 
{
   public:
      illegalInputData(string theMessage = "Illegal data input")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// illegal index
class illegalIndex 
{
   public:
      illegalIndex(string theMessage = "Illegal index")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// matrix index out of bounds
class matrixIndexOutOfBounds 
{
   public:
      matrixIndexOutOfBounds
            (string theMessage = "Matrix index out of bounds")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// matrix size mismatch
class matrixSizeMismatch 
{
   public:
      matrixSizeMismatch(string theMessage = 
                   "The size of the two matrics doesn't match")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// stack is empty
class stackEmpty
{
   public:
      stackEmpty(string theMessage = 
                   "Invalid operation on empty stack")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// queue is empty
class queueEmpty
{
   public:
      queueEmpty(string theMessage = 
                   "Invalid operation on empty queue")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// hash table is full
class hashTableFull
{
   public:
      hashTableFull(string theMessage = 
                   "The hash table is full")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// edge weight undefined
class undefinedEdgeWeight
{
   public:
      undefinedEdgeWeight(string theMessage = 
                   "No edge weights defined")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};

// method undefined
class undefinedMethod
{
   public:
      undefinedMethod(string theMessage = 
                   "This method is undefined")
            {message = theMessage;}
      void outputMessage() {cout << message << endl;}
   private:
      string message;
};
#endif



changeLength1D.h

// change the length of an array

#ifndef changeLength1D_
#define changeLength1D_

#include "myExceptions.h"

using namespace std;

template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
   if (newLength < 0)
      throw illegalParameterValue("new length must be >= 0");

   T* temp = new T[newLength];              // new array
   int number = min(oldLength, newLength);  // number to copy
   copy(a, a + number, temp);
   delete [] a;                             // deallocate old memory
   a = temp;
}

#endif


發佈了36 篇原創文章 · 獲贊 25 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章