首先,选定基准元素pivot,并且设置两个指针left和right,指向数列的最左和最右两个元素。
接下来进行第1次循环,从right指针开始,让指针所指向的元素和基准元素做比较。如果大于或等于pivot,则指针向左移动;如果小于pivot,则right指针停止移动,切换到left指针。
Class PHA.YX.Arithmetic.QuickSort Extends %RegisteredObject { Method quickSortBilateral(arr As PHA.YX.Arithmetic.Array, startIndex As %Integer, endIndex As %Integer) { /* 递归结束条件:startIndex大等于endIndex的时候 */ q:(startIndex >= endIndex) arr /* 得到基准元素位置 */ #dim pivotIndex as %Integer = ..partitionBilateral(arr, startIndex, endIndex) w "startIndex:" _ startIndex _" endIndex:" _ endIndex_" pivotIndex:" _ pivotIndex,! /* 根据基准元素,分成两部分递归排序 */ d ..quickSortBilateral(arr, startIndex, pivotIndex - 1) d ..quickSortBilateral(arr, pivotIndex + 1, endIndex) q arr } Method partitionBilateral(arr As PHA.YX.Arithmetic.Array, startIndex As %Integer, endIndex As %Integer) { /* 取第一个位置的元素作为基准元素(也可以选择随机位置) */ #dim pivot as %Integer = arr.get(startIndex) #dim left as %Integer = startIndex #dim right as %Integer = endIndex while (left '= right){ /* 控制right指针比较并左移 */ while ((left < right) && (arr.get(right) > pivot)){ w "first left:" _ left _" right:" _ right _ " arr.get(right):" _ arr.get(right) _" pivot:" _ pivot,! s right = right -1 } /* 控制left指针比较并右移 */ while ((left < right) && (arr.get(left) <= pivot)){ w "second left:" _ left _" right:" _ right _" arr.get(left):" _ arr.get(left) _" pivot:" _ pivot,! s left = left + 1 } /* 交换left和right指向的元素 */ if (left < right){ #dim p as %Integer = arr.get(left) d arr.set(left, arr.get(right)) d arr.set(right, p) } } d arr.set(startIndex, arr.get(left)) d arr.set(left, pivot) q left } }
/// w ##class(PHA.YX.Arithmetic).QuickSortBilateral() ClassMethod QuickSortBilateral() { s $zt = "ErrQuickSort" s array = ##class(PHA.YX.Arithmetic.Array).%New() d array.init(8) d array.insert(0,41) d array.insert(1,73) d array.insert(2,64) d array.insert(3,55) d array.insert(4,36) d array.insert(5,27) d array.insert(6,88) d array.insert(7,19) #dim mQuickSort as PHA.YX.Arithmetic.QuickSort = ##class(PHA.YX.Arithmetic.QuickSort).%New() s array = mQuickSort.quickSortBilateral(array, 0 ,array.length - 1) d array.output() q "" ErrQuickSort q $ze }
DHC-APP>w ##class(PHA.YX.Arithmetic).QuickSortBilateral() 19 27 36 41 55 64 73 88
而单边循环法则简单得多,只从数组的一边对元素进行遍历和交换。
给出原始数列如下,要求对其从小到大进行排序。
开始和双边循环法相似,首先选定基准元素pivot。同时,设置一个mark指针指向数列起始位置,这个mark指针代表小于基准元素的区域边界。
如果遍历到的元素大于基准元素,就继续往后遍历。如果遍历到的元素小于基准元素,则需要做两件事:第一,把mark指针右移1位,因为小于 pivot的区域边界增大了1;第二,让最新遍历到的元素和mark指针所在位置的元素交换位置,因为最新遍历的元素归属于小于pivot的区域。首先遍 历到元素7,7>4,所以继续遍历。
接下来遍历到的元素是3,3<4,所以mark指针右移1位。
随后,让元素3和mark指针所在位置的元素交换,因为元素3归属于小于pivot的区域。
剩余遍历
Method quickSortUnilateral(arr As PHA.YX.Arithmetic.Array, startIndex As %Integer, endIndex As %Integer) { /* 递归结束条件:startIndex大等于endIndex的时候 */ q:(startIndex >= endIndex) arr /* 得到基准元素位置 */ #dim pivotIndex as %Integer = ..partitionUnilateral(arr, startIndex, endIndex) w "startIndex:" _ startIndex _" endIndex:" _ endIndex_" pivotIndex:" _ pivotIndex,! /* 根据基准元素,分成两部分递归排序 */ d ..quickSortUnilateral(arr, startIndex, pivotIndex - 1) d ..quickSortUnilateral(arr, pivotIndex + 1, endIndex) q arr } Method partitionUnilateral(arr As PHA.YX.Arithmetic.Array, startIndex As %Integer, endIndex As %Integer) { /* 取第一个位置的元素作为基准元素(也可以选择随机位置) */ #dim pivot as %Integer = arr.get(startIndex) #dim mark as %Integer = startIndex for i = (startIndex + 1) : 1 : endIndex { if (arr.get(i) < pivot){ s mark = mark + 1 #dim p as %Integer = arr.get(mark) d arr.set(mark, arr.get(i)) d arr.set(i, p) } } d arr.set(startIndex, arr.get(mark)) d arr.set(mark, pivot) q mark }
/// w ##class(PHA.YX.Arithmetic).QuickSortUnilateral() ClassMethod QuickSortUnilateral() { s $zt = "ErrQuickSort" s array = ##class(PHA.YX.Arithmetic.Array).%New() d array.init(8) d array.insert(0,41) d array.insert(1,73) d array.insert(2,64) d array.insert(3,55) d array.insert(4,36) d array.insert(5,27) d array.insert(6,88) d array.insert(7,19) #dim mQuickSort as PHA.YX.Arithmetic.QuickSort = ##class(PHA.YX.Arithmetic.QuickSort).%New() s array = mQuickSort.quickSortUnilateral(array, 0 ,array.length - 1) d array.output() q "" ErrQuickSort q $ze }
DHC-APP>w ##class(PHA.YX.Arithmetic).QuickSortUnilateral() startIndex:0 endIndex:7 pivotIndex:3 startIndex:0 endIndex:2 pivotIndex:0 startIndex:1 endIndex:2 pivotIndex:2 startIndex:4 endIndex:7 pivotIndex:6 startIndex:4 endIndex:5 pivotIndex:4 19 27 36 41 55 64 73 88
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。