三路划分的快速排序算法

阅读清华大学殷人昆数据结构(第二版)c++语言描述一书时看到了三路划分的快速排序算法,书上给出的实现代码的宏观思路是正确的,但由于细节处理不当,代码本身无法运行。在网上查找了众多三路快排资料,无奈其中代码注释太少,阅读起来较为吃力,书上给出的代码无论如何修改调试都没法正常运行,一怒之下决定自己实现。以下给出的算法实现的分析细节较为繁琐,这里没有给出,如果不知道什么叫三路划分快排请查阅殷人昆数据结构第二版p412,这里直接给出c++实现

代码(C++,如有错误欢迎指出,共同学习共同进步)

  1 #include "stdafx.h"
  2 #include <vector>
  3 #include <algorithm>
  4 #include <iostream>
  5 using namespace std;
  6 typedef int type;
  7 
  8 void lmove(vector<type> &list, type left, type p, type &i)  //将左侧与基准元素相等的元素移至中间
  9 {
 10     type temp = i;
 11     type k = left;
 12     while (k <= p)
 13     {
 14         swap(list[k], list[i]);
 15         ++k;
 16         --i;
 17         if (i == p)
 18         {
 19             i = temp - p - 1 + left;
 20             break;
 21         }
 22     }
 23 }
 24 
 25 void rmove(vector<type> &list, type right, type q, type &j)  //将右侧与基准元素相等的元素移至中间
 26 {
 27     type temp = j;
 28     type k = right;
 29     while (k >= q)
 30     {
 31         swap(list[k], list[j]);
 32         --k;
 33         ++j;
 34         if (j == q)
 35         {
 36             j = 3 * q - temp - right + 1;
 37             break;
 38         }
 39     }
 40 }
 41 
 42 void quicksort(vector<type> &list, type left, type right)   //三路划分的快速排序算法
 43 {
 44     if (left >= right)
 45         return;
 46 
 47     type p = left - 1;
 48     type i = left - 1;
 49     type q = right;
 50     type j = right;
 51     int pv = list[right];
 52 
 53     while (1)
 54     {
 55         if (!(i == p && p == left - 1))
 56         {
 57             if (j - i == 1)
 58             {
 59                 if (i == p && p != left - 1)
 60                 {
 61                     ++i;
 62                 }
 63                 else
 64                 {
 65                     --j;
 66                 }
 67                 break;
 68             }
 69         }
 70 
 71         type tempi = i;
 72         if ((i == p && p != left - 1)|| (i == p && p == left - 1))
 73         {
 74             ++i;
 75         }
 76 
 77         while (list[i] < pv)
 78         {
 79             ++i;
 80             if (i == j)
 81                 break;
 82         }
 83         if (i == j)
 84             break;
 85 
 86         if (i + 1 == j)
 87         {
 88             if (list[i] == pv)
 89             {
 90                 if (tempi != p && j == q)
 91                 {
 92                     --j;
 93                     --q;
 94                     break;
 95                 }
 96                 else
 97                 {
 98                     if (j + 1 == q)
 99                     {
100                         swap(list[i], list[j]);
101                         --j;
102                         --q;
103                         break;
104                     }
105                     else
106                     {
107                         --q;
108                         swap(list[i], list[q]);
109                         --j;
110                         break;
111                     }
112                 }
113             }
114             else
115             {
116                 --j;
117                 break;
118             }
119         }
120 
121         type tempj = j;
122         if ((tempi != p && tempj == q) || (tempi == p && p == left - 1))
123             --j;
124         while (list[j] > pv)
125         {
126             --j;
127             if (i == j)
128                 break;
129         }
130 
131         if (i == j)
132         {
133             if (list[i] == pv)
134             {
135                 if (tempi != p && tempj == q)
136                 {
137                     if (i + 2 == q)
138                     {
139                         swap(list[i], list[j+1]);
140                         --q;
141                         break;
142                     }
143                     else
144                     {
145                         --q;
146                         swap(list[q], list[i]);
147                         break;
148                     }
149                 }
150                 else
151                 {
152                     --q;
153                     swap(list[q], list[i]);
154                     break;
155                 }
156             }
157             else
158             {
159                 break;
160             }
161         }
162         else
163         {
164             swap(list[i], list[j]);
165             type tempp = p;
166             if (list[i] == pv)
167             {
168                 if (tempi == p)
169                 {
170                     if (p + 1 == i)
171                     {
172                         ++p;
173                     }
174                     else
175                     {
176                         ++p;
177                         swap(list[i], list[p]);
178                     }
179                 }
180                 else
181                 {
182                     ++p;
183                     swap(list[i], list[p]);
184                 }
185             }
186 
187             if (list[j] == pv)
188             {
189                 if ((tempi != tempp && tempj == q) || tempi == tempp && (tempp == left - 1 || (tempp != left - 1 && tempj == q)))
190                 {
191                     if (j + 1 == q)       
192                     {
193                         --q;
194                     }
195                     else
196                     {
197                         --q;
198                         swap(list[j], list[q]);
199                     }
200                 }
201                 else
202                 {
203                     --q;
204                     swap(list[j], list[q]);
205                 }
206             }
207         }
208     }
209 
210     if (q - p <= 1)
211         return;
212     else
213     {
214         if (p != left - 1)
215         {
216             if (i == p)
217             {
218                 i = left - 1;
219                 ++j;
220                 rmove(list, right, q, j);
221             }
222             else
223             {
224                 if (i == q)
225                 {
226                     j = right + 1;
227                     --i;
228                     lmove(list, left, p, i);
229                 }
230                 else
231                 {
232                     if (list[i] < pv)
233                     {
234                         lmove(list, left, p, i);
235                         if (j + 1 == q)
236                         {
237                             j = right + 1;
238                         }
239                         else
240                         {
241                             ++j;
242                             rmove(list, right, q, j);
243                         }
244                     }
245                     else
246                     {
247                         rmove(list, right, q, j);
248                         if (i - 1 == p)
249                         {
250                             i = left - 1;
251                         }
252                         else
253                         {
254                             --i;
255                             lmove(list, left, p, i);
256                         }
257                     }
258                 }
259             }
260         }
261         else
262         {
263             if (i == q)
264             {
265                 --i;
266                 j = right + 1;
267             }
268             else
269             {
270                 if (list[i] < pv)
271                 {
272                     if (j + 1 == q)
273                     {
274                         j = right + 1;
275                     }
276                     else
277                     {
278                         ++j;
279                         rmove(list, right, q, j);
280                     }
281                 }
282                 else
283                 {
284                     rmove(list, right, q, j);
285                     if (i - 1 == p)
286                     {
287                         i = left - 1;
288                     }
289                     else
290                     {
291                         --i;
292                     }
293                 }
294             }
295         }
296     }
297 
298     quicksort(list, left, i);
299     quicksort(list, j, right);
300 }
301 
302 int main()
303 {
304     vector<type> list{ 2, 23, 6, 8, 5, 25, 19, 17, 25, 23, 18, 13, 25, 16, 23, 1, 9 };
305     cout << "排序前:";
306     for (const type &m : list)
307     {
308         cout << m << " ";
309     }
310     cout << endl;
311 
312     quicksort(list, 0, list.size()-1);
313 
314     cout << "排序后:";
315     for (const type &m : list)
316     {
317         cout << m << " ";
318     }
319     cout << endl;
320     return 0;
321 }

 运行结果:

 

猜你喜欢

转载自www.cnblogs.com/WSKIT/p/9148707.html
今日推荐