【算法导论】堆排序实现

来源:互联网 发布:淘宝美工是干什么的 编辑:程序博客网 时间:2024/05/18 03:54

我创建了一个Heap的数据结构,而不是像STL那样使用函数解决堆排序,当然STL的比较优雅一点,我只是提供第二个思路

#ifndef HEAP_SORT_H#define HEAP_SORT_H#include <vector>#include <cstddef>#include <iterator>#ifdef _DEBUG#include <iostream>#endif // _DEBUGtemplate <typename T>struct less {bool operator() (const T& lhs, const T& rhs){return lhs < rhs;}};//////////////////////////////////////////////////////////////////////////// 最大堆,用于实现堆排序// 算法思路://利用堆这种数据结构的特性,实现排序//在这里的思路是Heap含有一个vec,并没有事实能够证明继承比包含好用//////////////////////////////////////////////////////////////////////////template <typename T, typename Container = std::vector<T>, typename Compare = less<T> >class MaxHeap {public:typedef size_tpos_type;typedef size_tsize_type;typedef ptrdiff_tdiff_type;public:template <typename Iterator>MaxHeap(Iterator first, Iterator last) : vec(first, last), comp(Compare()){this->build_max_heap();#ifdef _AL_DEBUG// Show the original squencefor (; first != last; ++first){std::cout << *first << " ";}std::cout << std::endl;// Show the squence after build_max_heap()for (std::vector<T>::iterator iter = vec.begin();  iter != vec.end(); ++iter){std::cout << *iter << " ";}std::cout << std::endl;#endif // _AL_DEBUG}virtual ~MaxHeap() { }inline size_type size() const{return (size_type) this->vec.size();}inline size_type capacity() const{return (size_type) this->vec.capacity();}inline const T& top() const{return this->first();}inline bool pop(){if (size() == 0) return false;this->swap(1, size());// delete begin in vecthis->vec.pop_back();// do max heapifythis->max_heapify(_START_POS);// test the size of vecreturn true;}inline void push(const T& new_val){this->vec.push_back(new_val);this->update_heapify(this->size());}protected:Container vec;Compare comp;protected:inline pos_type parent(pos_type i) const{return i >> 1;}inline pos_type right(pos_type i) const{return (i << 1) + 1;}inline pos_type left(pos_type i) const{return i << 1;}inline bool has_left(pos_type i) const{if (left(i) > size() || left(i) < _START_POS) return false;else return true;}inline bool has_right(pos_type i) const{if (right(i) > size() || right(i) < _START_POS) return false;else return true;}inline bool has_parent(pos_type i) const{if (parent(i) < _START_POS) return false;else return true;}inline const T& value(pos_type i) const{return vec[--i];}inline const T& first() const{return vec[0];}inline void swap(pos_type lhs, pos_type rhs){--lhs, --rhs;Container::iterator left = this->vec.begin() + lhs;Container::iterator right = this->vec.begin() + rhs;T tmp = *left;*left = *right;*right = tmp;}// 建堆操作,时间复杂度:O(n)void build_max_heap(){pos_type last_pos = vec.size();#ifdef _AL_DEBUGstd::cout << "Size: " << last_pos << std::endl;#endif // _AL_DEBUGif (has_parent(last_pos)){for (pos_type p = parent(last_pos); p != 0; --p){max_heapify(p);}}}// 保持堆性质操作,时间复杂度:O(lgn)void max_heapify(pos_type pos){pos_type max_pos = pos;pos_type left_pos = left(pos);pos_type right_pos = right(pos);#ifdef _AL_DEBUGstd::cout << "max_heapify "  << pos << " " << left_pos << " " << right_pos << " ";std::cout << "max_heapify " << value(pos) << " ";#endif // _AL_DEBUG// Do exchange among this 3 nodes// and record the max one to max_pos// or the value of max_pos will not// be changedif (has_left(pos) && comp(value(max_pos), value(left_pos))){max_pos = left_pos;#ifdef _AL_DEBUGstd::cout << value(left_pos) << " ";#endif // _AL_DEBUG}if (has_right(pos) && comp(value(max_pos), value(right_pos))){max_pos = right_pos;#ifdef _AL_DEBUGstd::cout << value(right_pos);#endif // _AL_DEBUG}#ifdef _AL_DEBUG std::cout << std::endl;#endif // _AL_DEBUGif (max_pos != pos){swap(max_pos, pos);max_heapify(max_pos);}}void update_heapify(pos_type p){pos_type cur = p;pos_type parent_pos = parent(cur);while (has_parent(cur)){#ifdef _AL_DEBUG// Show the squence after build_max_heap()for (std::vector<T>::iterator iter = vec.begin(); iter != vec.end(); ++iter){std::cout << *iter << " ";}std::cout << std::endl;#endif // _AL_DEBUGif (comp(value(parent_pos), value(cur))){swap(parent_pos, cur);cur = parent_pos;parent_pos = parent(cur);}else break;}}static const size_type _START_POS = 1;};template <typename Iterator>void heap_sort(Iterator first, Iterator last){_heap_sort_aux(first, last, std::_Val_type(first));}//////////////////////////////////////////////////////////////////////////// 因为借助vector实现的,而不是自己利用allocator实现的,所以没办法控制// heap-sort过程中将最大值放在末尾的步骤,所以只能将最大值赋给当前的指针// 指向的位置//////////////////////////////////////////////////////////////////////////template <typename Iterator, typename Val>void _heap_sort_aux(Iterator first, Iterator last, Val*){MaxHeap<Val> heap(first, last);for (; first != last && heap.size() != 0; ++first){*first = heap.top();heap.pop();}}#endif


0 0
原创粉丝点击