acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
sort_list.h
1#pragma once
2
3
4namespace sort
5{
6
7 template <class TYPE, class ARG_TYPE, class ARRAY_TYPE>
8 void QuickSortAsc(comparable_list_base < TYPE, ARG_TYPE, ARRAY_TYPE > & list_base)
9 {
10 ::raw_array < POSITION > stackLowerBound;
11 ::raw_array < POSITION > stackUpperBound;
12 POSITION iLowerBound;
13 POSITION iUpperBound;
14 POSITION iLPos, iUPos, iMPos;
15
16 if(list_base.get_size() >= 2)
17 {
18 stackLowerBound.push(list_base.get_head_position());
19 stackUpperBound.push(list_base.get_tail_position());
20 while(true)
21 {
22 iLowerBound = stackLowerBound.pop();
23 iUpperBound = stackUpperBound.pop();
24 iLPos = iLowerBound;
25 iMPos = iLowerBound;
26 iUPos = iUpperBound;
27 while(true)
28 {
29 while(true)
30 {
31 if(iMPos == iUPos)
32 break;
33 if(list_base.get_at(iMPos) < list_base.get_at(iUPos))
34 list_base.get_previous(iUPos);
35 else
36 {
37 list_base.__swap(iMPos, iUPos);
38 break;
39 }
40 }
41 if(iMPos == iUPos)
42 break;
43 iMPos = iUPos;
44 while(true)
45 {
46 if(iMPos == iLPos)
47 break;
48 if(list_base.get_at(iLPos) < list_base.get_at(iMPos))
49 list_base.get_next(iLPos);
50 else
51 {
52 list_base.__swap(iLPos, iMPos);
53 break;
54 }
55 }
56 if(iMPos == iLPos)
57 break;
58 iMPos = iLPos;
59 }
60 if(list_base.position_index(iLowerBound) < list_base.position_index(iMPos) - 1)
61 {
62 stackLowerBound.push(iLowerBound);
63 stackUpperBound.push(iMPos - 1);
64 }
65 if(list_base.position_index(iMPos) + 1 < list_base.position_index(iUpperBound))
66 {
67 stackLowerBound.push(iMPos + 1);
68 stackUpperBound.push(iUpperBound);
69 }
70 if(stackLowerBound.get_size() == 0)
71 break;
72 }
73 }
74 }
75
76 template <class TYPE, class ARG_TYPE, class ARRAY_TYPE>
77 void QuickSortDesc(comparable_list_base < TYPE, ARG_TYPE, ARRAY_TYPE > & list_base)
78 {
79 ::raw_array < POSITION > stackLowerBound;
80 ::raw_array < POSITION > stackUpperBound;
81 POSITION iLowerBound;
82 POSITION iUpperBound;
83 POSITION iLPos, iUPos, iMPos;
84
85 if(list_base.get_size() >= 2)
86 {
87 stackLowerBound.push(list_base.get_head_position());
88 stackUpperBound.push(list_base.get_tail_position());
89 while(true)
90 {
91 iLowerBound = stackLowerBound.pop();
92 iUpperBound = stackUpperBound.pop();
93 iLPos = iLowerBound;
94 iMPos = iLowerBound;
95 iUPos = iUpperBound;
96 while(true)
97 {
98 while(true)
99 {
100 if(iMPos == iUPos)
101 break;
102 if(list_base.get_at(iUPos) < list_base.get_at(iMPos))
103 list_base.get_previous(iUPos);
104 else
105 {
106 list_base.__swap(iMPos, iUPos);
107 break;
108 }
109 }
110 if(iMPos == iUPos)
111 break;
112 iMPos = iUPos;
113 while(true)
114 {
115 if(iMPos == iLPos)
116 break;
117 if(list_base.get_at(iMPos) < list_base.get_at(iLPos))
118 list_base.get_next(iLPos);
119 else
120 {
121 list_base.__swap(iLPos, iMPos);
122 break;
123 }
124 }
125 if(iMPos == iLPos)
126 break;
127 iMPos = iLPos;
128 }
129 if(list_base.position_index(iLowerBound) < list_base.position_index(iMPos) - 1)
130 {
131 stackLowerBound.push(iLowerBound);
132 stackUpperBound.push(iMPos - 1);
133 }
134 if(list_base.position_index(iMPos) + 1 < list_base.position_index(iUpperBound))
135 {
136 stackLowerBound.push(iMPos + 1);
137 stackUpperBound.push(iUpperBound);
138 }
139 if(stackLowerBound.get_size() == 0)
140 break;
141 }
142 }
143 }
144
145 template < class ARRAY >
146 inline bool sort_find(ARRAY & a, typename ARRAY::BASE_ARG_TYPE arg,::collection::index & iIndex, ::collection::index iStart, ::collection::index iEnd)
147 {
148 if(a.get_size() == 0)
149 {
150 return false;
151 }
152 ::collection::index iLowerBound = iStart;
153 ::collection::index iMaxBound = iEnd;
154 ::collection::index iUpperBound = iMaxBound;
155 memsize iCompare;
156 // do binary search
157 iIndex = (iUpperBound + iLowerBound) / 2;
158 while(iUpperBound - iLowerBound >= 8)
159 {
160 iCompare = CompareElements(a.element_at(iIndex),arg);
161 if(iCompare == 0)
162 {
163 return true;
164 }
165 else if(iCompare > 0)
166 {
167 iUpperBound = iIndex - 1;
168 if(iUpperBound < 0)
169 {
170 iIndex = 0;
171 break;
172 }
173 }
174 else
175 {
176 iLowerBound = iIndex + 1;
177 if(iLowerBound > iMaxBound)
178 {
179 iIndex = iMaxBound + 1;
180 break;
181 }
182 }
183 iIndex = (iUpperBound + iLowerBound) / 2;
184 }
185 // do sequential search
186 while(iIndex < a.get_count())
187 {
188 iCompare = CompareElements(a.element_at(iIndex),arg);
189 if(iCompare == 0)
190 return true;
191 else if(iCompare < 0)
192 iIndex++;
193 else
194 break;
195 }
196 if(iIndex >= a.get_count())
197 return false;
198 while(iIndex >= 0)
199 {
200 iCompare = CompareElements(a.element_at(iIndex),arg);
201 if(iCompare == 0)
202 return true;
203 else if(iCompare > 0)
204 iIndex--;
205 else
206 break;
207 }
208 iIndex++;
209 return false;
210
211 }
212
213
214} // namespace sort
215
216
217
218
219//#include "collection_sort_array.h"
220#include "collection_key_sort_array.h"
221
222
223//template < class TYPE, class ARG_TYPE, class ARRAY_TYPE>
224//void comparable_array< TYPE, ARG_TYPE, ARRAY_TYPE >::quick_sort(bool bAsc)
225//{
226// if(bAsc)
227// {
228// sort::QuickSortAsc(*this);
229// }
230// else
231// {
232// sort::QuickSortDesc(*this);
233// }
234//}
235
236
237
238
239
240
241
242template < class TYPE, class ARG_TYPE, class ARRAY_TYPE>
244quick_sort(bool bAsc)
245{
246 if(bAsc)
247 {
248 sort::QuickSortAsc(*this);
249 }
250 else
251 {
252 sort::QuickSortDesc(*this);
253 }
254}
255
256template < class KEY, class TYPE, class ARG_TYPE , class ARRAY >
257void key_sort_array < KEY, TYPE, ARG_TYPE, ARRAY >::
258SetKeyProperty(KEY (TYPE::* lpfnKeyProperty)())
259{
260 m_lpfnKeyProperty= lpfnKeyProperty;
261 sort::QuickSortByKey < KEY, TYPE, ARG_TYPE >(
262 m_array,
263 m_lpfnKeyProperty);
264}
265
266
Definition comparable_list.h:11