【Delphi】对 QuickSort 函数的理解
2012-01-01 16:14
330 查看
在 Delphi 的 Classes 单元定义了 TList 类,TList 有一个 Sort 方法,用来对 TList 里面的指针数组进行排序,这个方法调用了 QuickSort 函数,这个函数不好理解,我看了很久才看明白。记录下来,以免将来忘记了。
个人能力有限,理解难免有偏差,如果有更好的解释,欢迎批评指正!
.
.
{ 对指针进行排序,Compare 为排序函数 } procedure TList.Sort(Compare: TListSortCompare); begin if (FList <> nil) and (Count > 1) then { 调用 Compare 进行排序 } QuickSort(FList, 0, Count - 1, function(Item1, Item2: Pointer): Integer begin Result := Compare(Item1, Item2); end); end; TListSortCompare = function (Item1, Item2: Pointer): Integer; { 快速排序过程 } { SortList:指针数组 L:排序范围的最左边(头) R:排序范围的最右边(尾) SCompare:比较两个指针所指内容大小的函数 } procedure QuickSort(SortList: PPointerList; L, R: Integer; SCompare: TListSortCompareFunc); var I, J: Integer; { 用来移动并查找元素的位置值 } P, T: Pointer; { 存放中间元素和临时元素 } begin repeat { 设定刚开始查找时的起始位置 I 和结束位置 J } I := L; { 最小 Index } J := R; { 最大 Index } { 获取范围正中间的元素 P 的值 } { (L + R) shr 1 相当于 (L + R) div 2 } P := SortList^[(L + R) shr 1]; repeat { 从 I 开始向后找比 P 大(>=)的元素 } while SCompare(SortList^[I], P) < 0 do Inc(I); { 从 J 开始向前找比 P 小(<=)的元素 } while SCompare(SortList^[J], P) > 0 do Dec(J); { 判断 I 和 J 是否碰过头(I > J 就表示已经碰过头了) } { 刚碰头不算,碰头后继续走一步才算碰过头 } if I <= J then begin { 如果还没有碰头,则交换 I 和 J 的元素值,小的排前面,大的排后面 } { 如果 I 和 J 刚碰头并且都指向同一个元素(I = J),则没必要自己和自己交换 } if I <> J then begin T := SortList^[I]; SortList^[I] := SortList^[J]; SortList^[J] := T; end; { I 和 J 各自向各自方向走一步,继续比较下一个元素 } Inc(I); Dec(J); end; { 如果已经碰过头,则退出此轮循环 } { 此时应该是 I := J + 1,即:I 在 J 的后面,并且紧挨着 J } until I > J; { 经过这样的一轮循环,此时 J 前面的元素全部都小于等于 P,J 后面的元素全部都大于等于 P,与 P 相等的元素(重复出现的元素,等 P 元素)会在 J 的前后换来换去,位置不定,不过没关系,将来 J 前面的一串元素(串1)会作为一个整体再次排序,那么与 P 相等的元素(等 P 元素)就会排在串后(串1的最后),而 J 后面的一串元素(串2)也会作为一个整体再次排序,那么与 P 相等的元素(等 P 元素)就会排在串前(串2的前面),这样两串元素(“串1”与“串2”)在 J 的位置相连接,就把所有与 P 相等的元素(等 P 元素)连在一起了 } { L < J 表示 J 前面还有元素需要排序,这些元素也就是上面所说的小于 P 的元素,(也就是“串1”) } { 递归调用 QuickSort 函数对“串1”进行排序 } if L < J then QuickSort(SortList, L, J, SCompare); { 经过一层或多层递归处理后,“串1”已经被全部排序完毕,接下来就要处理 J 后面的元素了,也就是“串2” } { 此时 I 刚好在 J 的后面紧挨着 J,所以从 I 开始后面元素的为“串2” } { 将 I 作为范围的起始位置,范围的结束位置不变,继续处理“串2” } L := I; { 直到 I 走到整个数组的最后,表示再没有元素需要被移动 } until I >= R; { 此时,整个指针数组排序完毕 } end;
个人能力有限,理解难免有偏差,如果有更好的解释,欢迎批评指正!
.
.
相关文章推荐
- 【Delphi】对 QuickSort 函数的理解分类
- Delphi-IOCP学习笔记<二>====IOCP基本函数介绍和理解
- 理解 Delphi 的类(十) - 深入方法[15] - 调用其他单元的函数
- [DELPHI-码农]理解 Delphi 的类(十) - 深入方法[15] - 调用其他单元的函数
- 理解 Delphi 的类(十) - 深入方法[5] - Result 与函数名
- 关系运算类系统函数样例以及绑定函数的理解应用
- 深入理解ECMAScript的函数参数
- 深度学习 6. MatConvNet 相关函数解释说明,MatConvNet 代码理解(二)cnn_mnist_init.m 的注释
- 【Linux】fork函数的理解
- 回调函数理解实例解析
- C++:虚函数理解
- 深入理解计算机系统(3.7)------过程(函数的调用原理)
- 基于C语言sprintf函数的深入理解
- 理解 Thread.Sleep 函数 ,Sleep(0) 释放当前线程所剩余的时间片,让线程马上回到就绪队列而非等待队列
- JS函数作用域及作用域链理解
- Delphi中获取星期几的函数
- AJAX入门之深入理解JavaScript中的函数
- JavaScript----函数深入理解
- 对引用和指针使用以及函数返回引用和指针类型的理解
- 梯度下降函数理解