阅读清华大学殷人昆数据结构(第二版)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 }
运行结果: