[算法初步]希尔排序 ##1 描述 ##2 场景 一群黑帮的大佬决定一起打一场牌,来小赌一把。于是他们来到一个赌场。3位大佬站在桌子的外围,发牌师站在桌子的内围。 然后发牌师开始发牌,大佬们拿到牌后,结果如下: *[3, 7, A] [K, 6, 4][ J, 5, 2] 结果大佬们很不满意,左边的大佬说我只要小牌,右边的大佬却只想要大牌。 结果经过跟发牌师协调,这3位将每个人面前的第一张牌3,J,K丢给发牌时,让他重新排列发还。 *[3, 7, A] [J, 6, 4] [K, 5 ,2 ] 然后又将第二张也丢给发牌时排列发还。第三张也如此。结果如下: *[3, 5, A] [J, 6, 2] [K, 7, 4] 这个虽然不是完全排序,比刚才的牌相对整齐一些,叫做基本有序了。 但是这个时候旁边两位大佬看不下了,说你们这样怎么行呢,我们俩也要玩。然后桌上的牌在不改变顺序的情况下重新分配 *[3,5][A,J][6,2][K,7][4] 左边的大佬拿的牌还不是最小,右边的大佬拿的牌也不是最大。大佬们决定继续按刚才的来,将第一张交给发牌师重新排列,然后第二张也是。 *[A,2][3,5][4,7][6,J][K] 结果还不是很满意,大佬们怒了。一个电话,又来了4个大佬。牌又分为如下: *[A] [2] [3] [5] [4] [7] [6] [J] [K] 然后所有的大佬又将牌交给发牌师重新排列,当发牌师排列完成,桌上的牌变成有序了。 *[A] [2] [3] [4] [5] [6] [7] [J] [K] 算法描述: 设定一个增量,将相隔一个增量的内容组成一个序列优先进行排序,这样使得当前的序列变得基本有序而不是局部有序。 这样不断减小增量,直到增量为1的时候所有牌变得有序。 伪代码 input: an array a of length n with array elements numbered 0 to n − 1 inc ← round(n/2) while inc > 0 do: for i = inc .. n − 1 do: temp ← a[i] j ← i while j ≥ inc and a[j − inc] > temp do: a[j] ← a[j − inc] j ← j − inc a[j] ← temp inc ← round(inc / 2.2) 3 go语言实现 package main import "fmt" /* * [希尔]场景: * 2 设定一个增量,将将相隔一个增量的内容组成一个序列优先进行排序。 * 7 重复步骤2,直到右边所有的牌都排序完成 */ func ShellSort(data *[9]int) { increment := len(data) var i, j int for { //获取增值 increment = increment/3 + 1 for i = increment; i < len(data); i++ { temp := data[i] j = i for ; j >= increment && data[j-increment] > temp; j = j - increment { data[j] = data[j-increment] } // 插入牌到移动后牌空出的位置上,在判断出的j位置之后 data[j] = temp } if increment <= 1 { break } } } /** * @param args */ func main() { data := [9]int{3, 5, 1, 7, 6, 2, 11, 13, 4} ShellSort(&data) for i := 0; i < len(data); i++ { fmt.Print(data[i]) fmt.Print(",") } }