sgi 之heap, priority_queue
生活随笔
收集整理的這篇文章主要介紹了
sgi 之heap, priority_queue
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
heap只能算是算法,而priority_queue只是封裝了vector,所以又稱為配接器。
由于在下面的實現中需要獲得iterator所指向的類型,所以又用到了stl中的類型萃取技術
cconstruct.h
#ifndef C_CONSTRUCT_H #define C_CONSTRUCT_H #include <iostream> #include <new.h>inline void destroy(char *, char *){} inline void destroy(int *, int *){} inline void destroy(long *, long *){} inline void destroy(float *, float *){} inline void destroy(double *, double *){}//對于int* p,也可以調用這個函數,比較怪異 template <class T> inline void destroy(T* pointer) {pointer->~T(); }template <class ForwardIterator> inline void destroy(ForwardIterator first, ForwardIterator last) {for (; first < last ; ++first)destroy(first); }template <class T1, class T2> inline void construct(T1* p, const T2& value) {new (p) T1(value); }template <class _Iter> inline typename std::iterator_traits<_Iter>::value_type* __value_type(const _Iter&) {return static_cast<typename std::iterator_traits<_Iter>::value_type*>(0); }#endifcheap.h
#ifndef C_HEAP_H #define C_HEAP_H #include "cconstruct.h" #include <iostream>//上溯。假設要上溯的值放在堆尾 template <class RandomAccessIterator, class Compare> void cpush_heap(RandomAccessIterator first, RandomAccessIterator last, Compare cmp ) {__cpush_heap(first, last, __value_type(first), cmp); }template <class RandomAccessIterator, class T, class Compare> void __cpush_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Compare cmp) {size_t holeIndex = last - first - 1;size_t parent = (holeIndex - 1)/2;T value = *(last - 1);while (holeIndex > 0 && cmp(*(first + parent), value)) {*(first + holeIndex) = *(first + parent);holeIndex = parent;parent = (holeIndex - 1)/2;}*(first + holeIndex) = value; }//上溯操作只適用于在尾部添加元素,維持堆特性的操作template <class RandomAccessIterator, class Compare> void cpop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare cmp) {__cpop_heap(first, last, __value_type(first), cmp); }template <class RandomAccessIterator, class T, class Compare> void __cpop_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Compare cmp) {T value = *(last - 1);*(last - 1) = *first;__cadjust_heap(first, 0, last - first - 1, value, cmp);//注意,此時的長度就不應該算上堆尾 }//向下走。value本來放在holeIndex template <class RandomAccessIterator, class T, class Compare> void __cadjust_heap(RandomAccessIterator first, size_t holeIndex, size_t len, T value, Compare cmp) {size_t firstChild = 2* holeIndex + 1;for ( ; firstChild < len; firstChild = 2* firstChild + 1) {if (firstChild + 1 < len && cmp(*(first + firstChild ), *(first + firstChild + 1)))++firstChild;if (!cmp(value, *(first + firstChild) ))//value >= childbreak;*(first + holeIndex) = *(first + firstChild);holeIndex = firstChild;}*(first + holeIndex) = value; }//輸入必須是已經成堆的 template <class RandomAccessIterator, class Compare> void csort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare cmp) {while (last - first > 1) cpop_heap(first, last--, cmp); }template <class RandomAccessIterator, class Compare> void cmake_heap(RandomAccessIterator first, RandomAccessIterator last, Compare cmp) {__cmake_heap(first, last, __value_type(first), cmp); }template <class RandomAccessIterator, class T,class Compare> void __cmake_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Compare cmp) {if (last - first < 2) return;size_t len = last - first;size_t holeIndex = (len - 2)/2;//從底向上,第一棵子樹的頭while (true) {__cadjust_heap(first, holeIndex, len, *(first + holeIndex), cmp);if (holeIndex == 0) return;--holeIndex;}}#endifcqueue.h #ifndef C_QUEUE_H #define C_QUEUE_H #include "cvector.h" #include "cheap.h" #include <iostream>template <class T, class Seq = cvector<T>, class Compare = less<typename Seq::value_type> > class cpriority_queue { public:typedef typename Seq::value_type value_type;typedef typename Seq::reference reference;typedef typename Seq::const_reference const_reference; protected:Seq c;//底層容器Compare comp;public:cpriority_queue() : c() {}template <class InputIterator>cpriority_queue(InputIterator first, InputIterator last, const Compare& x): c(first, last), comp(x) { cmake_heap(c.begin(), c.end(), comp); }template <class InputIterator>cpriority_queue(InputIterator first, InputIterator last): c(first, last){ cmake_heap(c.begin(), c.end(), comp); }/*void show() {Seq::iterator first = c.begin();for (;first != c.end(); ++first)std::cout<<*first<<" ";std::cout<<endl;}*/bool empty() const { return c.empty(); }size_t size() const { return c.size(); }const_reference top() const { return c.front(); }void push(const value_type& x) {c.push_back(x);cpush_heap(c.begin(), c.end(), comp);}void pop() {cpop_heap(c.begin(), c.end(), comp);c.pop_back();}};#endif
總結
以上是生活随笔為你收集整理的sgi 之heap, priority_queue的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sgi stl 之list
- 下一篇: 理解Node.js的异步非阻塞I/O模型