diff options
author | Mike Buland <eichlan@xagasoft.com> | 2008-02-19 19:30:09 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2008-02-19 19:30:09 +0000 |
commit | 62287ea894a1587553f017d0f6a09d4c87ad3b1f (patch) | |
tree | 154c6fbb6b3ef39c82809b6c3e3edaab8af71dbd /src/heap.h | |
parent | e2a10c7b77b03bacf4d8b8dcf08f8f8f47628314 (diff) | |
download | libbu++-62287ea894a1587553f017d0f6a09d4c87ad3b1f.tar.gz libbu++-62287ea894a1587553f017d0f6a09d4c87ad3b1f.tar.bz2 libbu++-62287ea894a1587553f017d0f6a09d4c87ad3b1f.tar.xz libbu++-62287ea894a1587553f017d0f6a09d4c87ad3b1f.zip |
I believe this will do the trick. The Bu::Heap class now uses the appropriate
allocators for all work, every data type used in a Bu::Heap must support the
equals operator and <= or >=, or you need to write your own comparison functor.
The heap works as both a min-heap and max-heap, just change out the functor used
for camparison, kinda' cool.
The print function I'll leave in for a little while, but not in the long run, it
just prints a dot graph to stdout.
Next up, the Ito version.
Diffstat (limited to 'src/heap.h')
-rw-r--r-- | src/heap.h | 61 |
1 files changed, 56 insertions, 5 deletions
@@ -12,10 +12,13 @@ | |||
12 | #include <string.h> | 12 | #include <string.h> |
13 | #include <memory> | 13 | #include <memory> |
14 | #include <iostream> | 14 | #include <iostream> |
15 | #include "bu/exceptionbase.h" | ||
15 | #include "bu/util.h" | 16 | #include "bu/util.h" |
16 | 17 | ||
17 | namespace Bu | 18 | namespace Bu |
18 | { | 19 | { |
20 | subExceptionDecl( HeapException ); | ||
21 | |||
19 | template<typename item> | 22 | template<typename item> |
20 | struct __basicLTCmp | 23 | struct __basicLTCmp |
21 | { | 24 | { |
@@ -24,26 +27,58 @@ namespace Bu | |||
24 | return a <= b; | 27 | return a <= b; |
25 | } | 28 | } |
26 | }; | 29 | }; |
30 | |||
31 | template<typename item> | ||
32 | struct __basicGTCmp | ||
33 | { | ||
34 | bool operator()( const item &a, const item &b ) | ||
35 | { | ||
36 | return a >= b; | ||
37 | } | ||
38 | }; | ||
39 | |||
40 | template<typename item> | ||
41 | struct __basicPtrLTCmp | ||
42 | { | ||
43 | bool operator()( const item &a, const item &b ) | ||
44 | { | ||
45 | return *a <= *b; | ||
46 | } | ||
47 | }; | ||
48 | |||
49 | template<typename item> | ||
50 | struct __basicPtrGTCmp | ||
51 | { | ||
52 | bool operator()( const item &a, const item &b ) | ||
53 | { | ||
54 | return *a >= *b; | ||
55 | } | ||
56 | }; | ||
27 | 57 | ||
28 | template<typename item, typename cmpfunc=__basicLTCmp<item>, typename itemalloc=std::allocator<item> > | 58 | template<typename item, typename cmpfunc=__basicLTCmp<item>, typename itemalloc=std::allocator<item> > |
29 | class Heap | 59 | class Heap |
30 | { | 60 | { |
31 | public: | 61 | public: |
32 | Heap() : | 62 | Heap() : |
33 | iSize( 40 ), | 63 | iSize( 7 ), |
34 | iFill( 0 ), | 64 | iFill( 0 ), |
35 | aItem( new item[iSize] ) | 65 | aItem( ia.allocate( iSize ) ) |
36 | { | 66 | { |
37 | } | 67 | } |
38 | 68 | ||
39 | virtual ~Heap() | 69 | virtual ~Heap() |
40 | { | 70 | { |
41 | delete[] aItem; | 71 | for( int j = 0; j < iFill; j++ ) |
72 | ia.destroy( &aItem[j] ); | ||
73 | ia.deallocate( aItem, iSize ); | ||
42 | aItem = NULL; | 74 | aItem = NULL; |
43 | } | 75 | } |
44 | 76 | ||
45 | void push( item i ) | 77 | void push( item i ) |
46 | { | 78 | { |
79 | if( iFill+1 >= iSize ) | ||
80 | upSize(); | ||
81 | |||
47 | for( int j = 0; j < iFill; ) | 82 | for( int j = 0; j < iFill; ) |
48 | { | 83 | { |
49 | if( cmp( i, aItem[j] ) ) | 84 | if( cmp( i, aItem[j] ) ) |
@@ -60,7 +95,7 @@ namespace Bu | |||
60 | j = j*2+2; | 95 | j = j*2+2; |
61 | } | 96 | } |
62 | } | 97 | } |
63 | aItem[iFill] = i; | 98 | ia.construct( &aItem[iFill], i ); |
64 | for( int j = iFill; j >= 0; ) | 99 | for( int j = iFill; j >= 0; ) |
65 | { | 100 | { |
66 | int k = (j-1)/2; | 101 | int k = (j-1)/2; |
@@ -75,11 +110,15 @@ namespace Bu | |||
75 | 110 | ||
76 | item &peek() | 111 | item &peek() |
77 | { | 112 | { |
113 | if( iFill == 0 ) | ||
114 | throw HeapException("Heap empty."); | ||
78 | return aItem[0]; | 115 | return aItem[0]; |
79 | } | 116 | } |
80 | 117 | ||
81 | void pop() | 118 | void pop() |
82 | { | 119 | { |
120 | if( iFill == 0 ) | ||
121 | throw HeapException("Heap empty."); | ||
83 | int j; | 122 | int j; |
84 | for( j = 0; j < iFill; ) | 123 | for( j = 0; j < iFill; ) |
85 | { | 124 | { |
@@ -97,6 +136,7 @@ namespace Bu | |||
97 | break; | 136 | break; |
98 | } | 137 | } |
99 | aItem[j] = aItem[iFill-1]; | 138 | aItem[j] = aItem[iFill-1]; |
139 | ia.destroy( &aItem[iFill-1] ); | ||
100 | iFill--; | 140 | iFill--; |
101 | } | 141 | } |
102 | 142 | ||
@@ -121,13 +161,24 @@ namespace Bu | |||
121 | ); | 161 | ); |
122 | } | 162 | } |
123 | printf("}\n"); | 163 | printf("}\n"); |
124 | } | 164 | } |
165 | |||
166 | private: | ||
167 | void upSize() | ||
168 | { | ||
169 | item *aNewItems = ia.allocate( iSize*2+1 ); | ||
170 | memcpy( aNewItems, aItem, sizeof(item)*iFill ); | ||
171 | ia.deallocate( aItem, iSize ); | ||
172 | aItem = aNewItems; | ||
173 | iSize = iSize*2+1; | ||
174 | } | ||
125 | 175 | ||
126 | private: | 176 | private: |
127 | int iSize; | 177 | int iSize; |
128 | int iFill; | 178 | int iFill; |
129 | item *aItem; | 179 | item *aItem; |
130 | cmpfunc cmp; | 180 | cmpfunc cmp; |
181 | itemalloc ia; | ||
131 | }; | 182 | }; |
132 | }; | 183 | }; |
133 | 184 | ||