第十三章 Caché 算法与数据结构 鸡尾酒排序
定义
- 冒泡排序的每一个元素都可以像小气泡一样,根据自身大小,一点一点地向着数组的一侧移动。算法的每一轮都是从左到右来比较元素,进行单向的位置交换的。
- 鸡尾酒排序的元素比较和交换过程是双向的。
示例
由8个数字组成一个无序数列{2,3,4,5,6,7,8,1},希望对其进行从小到大的排序。
如果按照冒泡排序的思想,排序过程如下。
鸡尾酒排序的思想
- 第1轮(和冒泡排序一样,8和1交换)
- 第二轮 反相对比
- 第三轮 实际上已经有序
排序过程类似钟摆一样
使用场景
- 是大部分元素已经有序的情况下
完整代码
排序类
Class PHA.YX.Arithmetic.CockTailSort Extends %RegisteredObject
{
Method sort(array As PHA.YX.Arithmetic.Array)
{
#dim tmp as %Integer = 0
for i = 0 : 1 : (array.length() / 2 - 1) {
/* 有序标记,每一轮的初始是true */
#dim isSorted as %Boolean = $$$YES
/* 奇数轮,从左向右比较和交换 */
for j = i : 1 : (array.length - i - 2){
;w "right i:"_ i_" j:"_ j_" array.get(j):"_ array.get(j)_" array.get(j + 1):"_array.get(j + 1),!
b:j=7
if (array.get(j) > array.get(j + 1)){
s tmp = array.get(j)
d array.set(j, array.get(j + 1))
d array.set(j + 1, tmp)
/* 有元素交换,所以不是有序,标记变为false */
s isSorted = $$$NO
}
}
if (isSorted){
continue
}
/* 偶数轮之前,重新标记为true */
s isSorted = $$$YES
/* 偶数轮,从右向左比较和交换 */
for j = (array.length - i -1) : -1 : i + 1 {
;w "left i:"_ i_" j:"_ j_" array.get(j):"_ array.get(j)_" array.get(j + 1):"_array.get(j + 1),!
if (array.get(j) < array.get(j - 1)){
s tmp = array.get(j)
d array.set(j, array.get(j - 1))
d array.set(j - 1, tmp)
/* 有元素交换,所以不是有序,标记变为false */
s isSorted = $$$NO
}
}
if (isSorted){
continue
}
}
q array
}
}
/// w ##class(PHA.YX.Arithmetic).CockTailSort()
ClassMethod CockTailSort()
{
s $zt = "ErrCockTailSort"
s array = ##class(PHA.YX.Arithmetic.Array).%New()
d array.init(8)
d array.insert(0,2)
d array.insert(1,3)
d array.insert(2,4)
d array.insert(3,5)
d array.insert(4,6)
d array.insert(5,7)
d array.insert(6,8)
d array.insert(7,1)
#dim mCockTailSort as PHA.YX.Arithmetic.CockTailSort = ##class(PHA.YX.Arithmetic.CockTailSort).%New()
s array = mCockTailSort.sort(array)
d array.output()
q ""
ErrCockTailSort
q $ze
}
DHC-APP>w ##class(PHA.YX.Arithmetic).CockTailSort()
1
2
3
4
5
6
7
8