排序算法总结

  1 unit unit2;
  2 
  3 interface
  4 
  5 // 冒泡排序
  6 procedure BubbleSort(var abc: array of Integer);
  7 
  8 // 摇动排序
  9 procedure ShakerSort(var abc: array of Integer);
 10 
 11 // 梳子排序
 12 procedure CombSort(var abc: array of Integer);
 13 
 14 // 选择排序
 15 procedure SelectionSort(var abc: array of Integer);
 16 
 17 // 标准插入排序
 18 procedure InsertionSortStd(var abc: array of Integer);
 19 
 20 // 优化的插入排序
 21 procedure InsertionSort(var abc: array of Integer);
 22 
 23 // 希尔排序
 24 procedure ShellSort(var abc: array of Integer);
 25 
 26 // 标准归并排序
 27 procedure MergeSortStd(var abc: array of Integer);
 28 
 29 // 优化的归并排序
 30 procedure MergeSort(var abc: array of Integer);
 31 
 32 // 标准快速排序
 33 procedure QuickSortStd(var abc: array of Integer);
 34 
 35 // 无递归的快速排序
 36 procedure QuickSortNoRecurse(var abc: array of Integer);
 37 
 38 // 随机的快速排序
 39 procedure QuickSortRandom(var abc: array of Integer);
 40 
 41 // 中间值的快速排序
 42 procedure QuickSortMedian(var abc: array of Integer);
 43 
 44 // 优化的插入快速排序
 45 procedure QuickSort(var abc: array of Integer);
 46 
 47 // 堆排序
 48 procedure HeapSort(var abc: array of Integer);
 49 
 50 implementation
 51 
 52 // 冒泡排序
 53 procedure BubbleSort(var abc: array of Integer);
 54 var
 55   i, j: Integer;
 56   Temp: Integer;
 57   Done: boolean;
 58 begin
 59   for i := 0 to High(abc) do
 60   begin
 61     Done  := true;
 62     for j := High(abc) + 1 downto 0 do
 63       if abc[j] < abc[j - 1] then
 64       begin
 65         Temp       := abc[j];
 66         abc[j]     := abc[j - 1];
 67         abc[j - 1] := Temp;
 68         Done       := false;
 69       end;
 70     if Done then
 71       Exit;
 72   end;
 73 end;
 74 
 75 // 梳子排序
 76 procedure CombSort(var abc: array of Integer);
 77 var
 78   i, j: Integer;
 79   Temp: Integer;
 80   Done: boolean;
 81   Gap:  Integer;
 82 begin
 83   Gap := High(abc);
 84   repeat
 85     Done := true;
 86     Gap  := (longint(Gap) * 10) div 13;
 87     if (Gap < 1) then
 88       Gap := 1
 89     else if (Gap = 9) or (Gap = 10) then
 90       Gap := 11;
 91     for i := 0 to (High(abc) - Gap) do
 92     begin
 93       j := i + Gap;
 94       if abc[j] < abc[i] then
 95       begin
 96         Temp   := abc[j];
 97         abc[j] := abc[i];
 98         abc[i] := Temp;
 99         Done   := false;
100       end;
101     end;
102   until Done and (Gap = 1);
103 end;
104 
105 // 标准插入排序
106 procedure InsertionSortStd(var abc: array of Integer);
107 var
108   i, j: Integer;
109   Temp: Integer;
110 begin
111   for i := 0 to High(abc) do
112   begin
113     Temp := abc[i];
114     j    := i;
115     while (j > 0) and (Temp < abc[j - 1]) do
116     begin
117       abc[j] := abc[j - 1];
118       dec(j);
119     end;
120     abc[j] := Temp;
121   end;
122 end;
123 
124 // 优化的插入排序
125 procedure InsertionSort(var abc: array of Integer);
126 var
127   i, j:       Integer;
128   IndexOfMin: Integer;
129   Temp:       Integer;
130 begin
131   IndexOfMin := 0;
132   for i      := 0 to High(abc) do
133     if abc[i] < abc[IndexOfMin] then
134       IndexOfMin := i;
135   if (0 <> IndexOfMin) then
136   begin
137     Temp            := abc[0];
138     abc[0]          := abc[IndexOfMin];
139     abc[IndexOfMin] := Temp;
140   end;
141   for i := 0 + 2 to High(abc) do
142   begin
143     Temp := abc[i];
144     j    := i;
145     while Temp < abc[j - 1] do
146     begin
147       abc[j] := abc[j - 1];
148       dec(j);
149     end;
150     abc[j] := Temp;
151   end;
152 end;
153 
154 // 选择排序
155 procedure SelectionSort(var abc: array of Integer);
156 var
157   i, j:       Integer;
158   IndexOfMin: Integer;
159   Temp:       Integer;
160 begin
161   for i := 0 to High(abc) do
162   begin
163     IndexOfMin := i;
164     for j      := i to High(abc) + 1 do
165       if abc[j] < abc[IndexOfMin] then
166         IndexOfMin  := j;
167     Temp            := abc[i];
168     abc[i]          := abc[IndexOfMin];
169     abc[IndexOfMin] := Temp;
170   end;
171 end;
172 
173 // 摇动排序
174 procedure ShakerSort(var abc: array of Integer);
175 var
176   i:          Integer;
177   Temp:       Integer;
178   iMin, iMax: Integer;
179 begin
180   iMin := 0;
181   iMax := High(abc) - Low(abc) + 1;
182 
183   while (iMin < iMax) do
184   begin
185     for i := iMax downto 0 do
186       if abc[i] < abc[i - 1] then
187       begin
188         Temp       := abc[i];
189         abc[i]     := abc[i - 1];
190         abc[i - 1] := Temp;
191       end;
192     inc(iMin);
193     for i := 0 to iMax do
194       if abc[i] < abc[i - 1] then
195       begin
196         Temp       := abc[i];
197         abc[i]     := abc[i - 1];
198         abc[i - 1] := Temp;
199       end;
200     dec(iMax);
201   end;
202 end;
203 
204 // 希尔排序
205 procedure ShellSort(var abc: array of Integer);
206 var
207   i, j:  Integer;
208   h:     Integer;
209   Temp:  Integer;
210   Ninth: Integer;
211 begin
212   h     := 1;
213   Ninth := High(abc) div 9;
214   while (h <= Ninth) do
215     h := (h * 3) + 1;
216   while (h > 0) do
217   begin
218     for i := h to High(abc) do
219     begin
220       Temp := abc[i];
221       j    := i;
222       while (j >= (0 + h)) and (Temp < abc[j - h]) do
223       begin
224         abc[j] := abc[j - h];
225         dec(j, h);
226       end;
227       abc[j] := Temp;
228     end;
229     h := h div 3;
230   end;
231 end;
232 
233 // 标准归并排序
234 procedure MergeSortStd(var abc: array of Integer);
235   procedure MSS(var abc: array of Integer; aFirst: Integer; aLast: Integer; aTempList: array of Integer);
236   var
237     Mid:        Integer;
238     i, j:       Integer;
239     ToInx:      Integer;
240     FirstCount: Integer;
241   begin
242     Mid := (aFirst + aLast) div 2;
243     if (aFirst < Mid) then
244       MSS(abc, aFirst, Mid, aTempList);
245     if (succ(Mid) < aLast) then
246       MSS(abc, succ(Mid), aLast, aTempList);
247     FirstCount := succ(Mid - aFirst);
248     Move(abc[aFirst], aTempList[0], FirstCount * sizeof(pointer));
249     i     := 0;
250     j     := succ(Mid);
251     ToInx := aFirst;
252     while (i < FirstCount) and (j <= aLast) do
253     begin
254       if (aTempList[i] <= abc[j]) then
255       begin
256         abc[ToInx] := aTempList[i];
257         inc(i);
258       end
259       else
260       begin
261         abc[ToInx] := abc[j];
262         inc(j);
263       end;
264       inc(ToInx);
265     end;
266     if (i < FirstCount) then
267       Move(aTempList[i], abc[ToInx], (FirstCount - i) * sizeof(pointer));
268   end;
269 
270 var
271   TempList: array of Integer;
272 begin
273   if (0 < High(abc)) then
274   begin
275     SetLength(TempList, High(abc) div 2);
276     MSS(abc, 0, High(abc), TempList);
277   end;
278 end;
279 
280 // 优化的归并排序
281 procedure MergeSort(var abc: array of Integer);
282 const
283   MSCutOff = 15;
284 
285   procedure MSInsertionSort(var abc: array of Integer; aFirst: Integer; aLast: Integer);
286   var
287     i, j:       Integer;
288     IndexOfMin: Integer;
289     Temp:       Integer;
290   begin
291     IndexOfMin := aFirst;
292     for i      := succ(aFirst) to aLast do
293       if abc[i] < abc[IndexOfMin] then
294         IndexOfMin := i;
295     if (aFirst <> IndexOfMin) then
296     begin
297       Temp            := abc[aFirst];
298       abc[aFirst]     := abc[IndexOfMin];
299       abc[IndexOfMin] := Temp;
300     end;
301     for i := aFirst + 2 to aLast do
302     begin
303       Temp := abc[i];
304       j    := i;
305       while Temp < abc[j - 1] do
306       begin
307         abc[j] := abc[j - 1];
308         dec(j);
309       end;
310       abc[j] := Temp;
311     end;
312   end;
313 
314   procedure MS(var abc: array of Integer; aFirst: Integer; aLast: Integer; aTempList: array of Integer);
315   var
316     Mid:        Integer;
317     i, j:       Integer;
318     ToInx:      Integer;
319     FirstCount: Integer;
320   begin
321     Mid := (aFirst + aLast) div 2;
322     if (aFirst < Mid) then
323       if (Mid - aFirst) <= MSCutOff then
324         MSInsertionSort(abc, aFirst, Mid)
325       else
326         MS(abc, aFirst, Mid, aTempList);
327     if (succ(Mid) < aLast) then
328       if (aLast - succ(Mid)) <= MSCutOff then
329         MSInsertionSort(abc, succ(Mid), aLast)
330       else
331         MS(abc, succ(Mid), aLast, aTempList);
332     FirstCount := succ(Mid - aFirst);
333     Move(abc[aFirst], aTempList[0], FirstCount * sizeof(pointer));
334     i     := 0;
335     j     := succ(Mid);
336     ToInx := aFirst;
337     while (i < FirstCount) and (j <= aLast) do
338     begin
339       if (aTempList[i] <= abc[j]) then
340       begin
341         abc[ToInx] := aTempList[i];
342         inc(i);
343       end
344       else
345       begin
346         abc[ToInx] := abc[j];
347         inc(j);
348       end;
349       inc(ToInx);
350     end;
351     if (i < FirstCount) then
352       Move(aTempList[i], abc[ToInx], (FirstCount - i) * sizeof(pointer));
353   end;
354 
355 var
356   TempList: array of Integer;
357 begin
358   if (0 < High(abc)) then
359   begin
360     SetLength(TempList, High(abc) div 2);
361     MS(abc, 0, High(abc), TempList);
362   end;
363 end;
364 
365 // 标准快速排序
366 procedure QuickSortStd(var abc: array of Integer);
367   procedure QSS(var abc: array of Integer; aFirst: Integer; aLast: Integer);
368   var
369     L, R:  Integer;
370     Pivot: Integer;
371     Temp:  Integer;
372   begin
373     while (aFirst < aLast) do
374     begin
375       Pivot := abc[(aFirst + aLast) div 2];
376       L     := pred(aFirst);
377       R     := succ(aLast);
378       while true do
379       begin
380         repeat
381           dec(R);
382         until (abc[R] <= Pivot);
383 
384         repeat
385           inc(L);
386         until (abc[L] >= Pivot);
387 
388         if (L >= R) then
389           Break;
390 
391         Temp   := abc[L];
392         abc[L] := abc[R];
393         abc[R] := Temp;
394       end;
395       if (aFirst < R) then
396         QSS(abc, aFirst, R);
397       aFirst := succ(R);
398     end;
399   end;
400 
401 begin
402   QSS(abc, 0, High(abc));
403 end;
404 
405 // 无递归的快速排序
406 procedure QuickSortNoRecurse(var abc: array of Integer);
407   procedure QSNR(var abc: array of Integer; aFirst: Integer; aLast: Integer);
408   var
409     L, R:  Integer;
410     Pivot: Integer;
411     Temp:  Integer;
412     Stack: array [0 .. 63] of Integer; { allows for 2 billion items }
413     SP:    Integer;
414   begin
415     Stack[0] := aFirst;
416     Stack[1] := aLast;
417     SP       := 2;
418     while (SP <> 0) do
419     begin
420       dec(SP, 2);
421       aFirst := Stack[SP];
422       aLast  := Stack[SP + 1];
423       while (aFirst < aLast) do
424       begin
425         Pivot := abc[(aFirst + aLast) div 2];
426         L     := pred(aFirst);
427         R     := succ(aLast);
428         while true do
429         begin
430           repeat
431             dec(R);
432           until (abc[R] <= Pivot);
433           repeat
434             inc(L);
435           until (abc[L] >= Pivot);
436           if (L >= R) then
437             Break;
438           Temp   := abc[L];
439           abc[L] := abc[R];
440           abc[R] := Temp;
441         end;
442         if (R - aFirst) < (aLast - R) then
443         begin
444           Stack[SP]     := succ(R);
445           Stack[SP + 1] := aLast;
446           inc(SP, 2);
447           aLast := R;
448         end
449         else
450         begin
451           Stack[SP]     := aFirst;
452           Stack[SP + 1] := R;
453           inc(SP, 2);
454           aFirst := succ(R);
455         end;
456       end;
457     end;
458   end;
459 
460 begin
461   QSNR(abc, 0, High(abc));
462 end;
463 
464 // 随机的快速排序
465 procedure QuickSortRandom(var abc: array of Integer);
466   procedure QSR(var abc: array of Integer; aFirst: Integer; aLast: Integer);
467   var
468     L, R:  Integer;
469     Pivot: Integer;
470     Temp:  Integer;
471   begin
472     while (aFirst < aLast) do
473     begin
474       R      := aFirst + Random(aLast - aFirst + 1);
475       L      := (aFirst + aLast) div 2;
476       Pivot  := abc[R];
477       abc[R] := abc[L];
478       abc[L] := Pivot;
479       L      := pred(aFirst);
480       R      := succ(aLast);
481       while true do
482       begin
483         repeat
484           dec(R);
485         until (abc[R] <= Pivot);
486         repeat
487           inc(L);
488         until (abc[L] >= Pivot);
489         if (L >= R) then
490           Break;
491         Temp   := abc[L];
492         abc[L] := abc[R];
493         abc[R] := Temp;
494       end;
495       if (aFirst < R) then
496         QSR(abc, aFirst, R);
497       aFirst := succ(R);
498     end;
499   end;
500 
501 begin
502   QSR(abc, 0, High(abc));
503 end;
504 
505 // 中间值的快速排序
506 procedure QuickSortMedian(var abc: array of Integer);
507   procedure QSM(var abc: array of Integer; aFirst: Integer; aLast: Integer);
508   var
509     L, R:  Integer;
510     Pivot: Integer;
511     Temp:  Integer;
512   begin
513     while (aFirst < aLast) do
514     begin
515       if (aLast - aFirst) >= 2 then
516       begin
517         R := (aFirst + aLast) div 2;
518         if (abc[aFirst] > abc[R]) then
519         begin
520           Temp        := abc[aFirst];
521           abc[aFirst] := abc[R];
522           abc[R]      := Temp;
523         end;
524         if (abc[aFirst] > abc[aLast]) then
525         begin
526           Temp        := abc[aFirst];
527           abc[aFirst] := abc[aLast];
528           abc[aLast]  := Temp;
529         end;
530         if (abc[R] > abc[aLast]) then
531         begin
532           Temp       := abc[R];
533           abc[R]     := abc[aLast];
534           abc[aLast] := Temp;
535         end;
536         Pivot := abc[R];
537       end
538       else
539         Pivot := abc[aFirst];
540       L       := pred(aFirst);
541       R       := succ(aLast);
542       while true do
543       begin
544         repeat
545           dec(R);
546         until (abc[R] <= Pivot);
547         repeat
548           inc(L);
549         until (abc[L] >= Pivot);
550         if (L >= R) then
551           Break;
552         Temp   := abc[L];
553         abc[L] := abc[R];
554         abc[R] := Temp;
555       end;
556       if (aFirst < R) then
557         QSM(abc, aFirst, R);
558       aFirst := succ(R);
559     end;
560   end;
561 
562 begin
563   QSM(abc, 0, High(abc));
564 end;
565 
566 // 优化插入的快速排序
567 procedure QuickSort(var abc: array of Integer);
568 const
569   QSCutOff = 15;
570 
571   procedure QSInsertionSort(var abc: array of Integer; aFirst: Integer; aLast: Integer);
572   var
573     i, j:       Integer;
574     IndexOfMin: Integer;
575     Temp:       Integer;
576   begin
577     IndexOfMin := aFirst;
578     j          := aFirst + QSCutOff; { !!.01 }
579     if (j > aLast) then
580       j   := aLast;
581     for i := succ(aFirst) to j do
582       if abc[i] < abc[IndexOfMin] then
583         IndexOfMin := i;
584     if (aFirst <> IndexOfMin) then
585     begin
586       Temp            := abc[aFirst];
587       abc[aFirst]     := abc[IndexOfMin];
588       abc[IndexOfMin] := Temp;
589     end;
590     { now sort via fast insertion method }
591     for i := aFirst + 2 to aLast do
592     begin
593       Temp := abc[i];
594       j    := i;
595       while Temp < abc[j - 1] do
596       begin
597         abc[j] := abc[j - 1];
598         dec(j);
599       end;
600       abc[j] := Temp;
601     end;
602   end;
603 
604   procedure QS(var abc: array of Integer; aFirst: Integer; aLast: Integer);
605   var
606     L, R:  Integer;
607     Pivot: Integer;
608     Temp:  Integer;
609     Stack: array [0 .. 63] of Integer; { allows for 2 billion items }
610     SP:    Integer;
611   begin
612     Stack[0] := aFirst;
613     Stack[1] := aLast;
614     SP       := 2;
615 
616     while (SP <> 0) do
617     begin
618       dec(SP, 2);
619       aFirst := Stack[SP];
620       aLast  := Stack[SP + 1];
621 
622       while ((aLast - aFirst) > QSCutOff) do
623       begin
624         R := (aFirst + aLast) div 2;
625         if (abc[aFirst] > abc[R]) then
626         begin
627           Temp        := abc[aFirst];
628           abc[aFirst] := abc[R];
629           abc[R]      := Temp;
630         end;
631         if (abc[aFirst] > abc[aLast]) then
632         begin
633           Temp        := abc[aFirst];
634           abc[aFirst] := abc[aLast];
635           abc[aLast]  := Temp;
636         end;
637         if (abc[R] > abc[aLast]) then
638         begin
639           Temp       := abc[R];
640           abc[R]     := abc[aLast];
641           abc[aLast] := Temp;
642         end;
643         Pivot := abc[R];
644 
645         L := aFirst;
646         R := aLast;
647         while true do
648         begin
649           repeat
650             dec(R);
651           until (abc[R] <= Pivot);
652           repeat
653             inc(L);
654           until (abc[L] >= Pivot);
655           if (L >= R) then
656             Break;
657           Temp   := abc[L];
658           abc[L] := abc[R];
659           abc[R] := Temp;
660         end;
661 
662         if (R - aFirst) < (aLast - R) then
663         begin
664           Stack[SP]     := succ(R);
665           Stack[SP + 1] := aLast;
666           inc(SP, 2);
667           aLast := R;
668         end
669         else
670         begin
671           Stack[SP]     := aFirst;
672           Stack[SP + 1] := R;
673           inc(SP, 2);
674           aFirst := succ(R);
675         end;
676       end;
677     end;
678   end;
679 
680 begin
681   QS(abc, 0, High(abc));
682   QSInsertionSort(abc, 0, High(abc));
683 end;
684 
685 // 堆排序
686 procedure HeapSort(var abc: array of Integer);
687   procedure HSTrickleDown(var abc: array of Integer; root, count: Integer);
688   var
689     KKK: Integer;
690   begin
691     abc[0] := abc[root];
692     KKK    := 2 * root;
693     while KKK <= count do
694     begin
695       if (KKK < count) and (abc[KKK] < abc[KKK + 1]) then
696         inc(KKK);
697       if abc[0] < abc[KKK] then
698       begin
699         abc[root] := abc[KKK];
700         root      := KKK;
701         KKK       := 2 * root;
702       end
703       else
704         KKK := count + 1;
705     end;
706     abc[root] := abc[0];
707   end;
708 
709 var
710   Inx:       Integer;
711   ItemCount: Integer;
712   tmp:       Integer;
713 begin
714   ItemCount := High(abc) - Low(abc) + 1;
715   for Inx   := ItemCount div 2 downto 1 do
716   begin
717     HSTrickleDown(abc, Inx, ItemCount);
718   end;
719 
720   for Inx := ItemCount downto 2 do
721   begin
722     tmp      := abc[1];
723     abc[1]   := abc[Inx];
724     abc[Inx] := tmp;
725     HSTrickleDown(abc, 1, Inx - 1);
726   end;
727 end;
728 
729 end.


 

posted @ 2013-09-12 15:44  Max Woods  阅读(750)  评论(0编辑  收藏  举报