[算法初步]希尔排序

[算法初步]希尔排序
##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(",")
		}
	}
posted @ 2013-04-22 20:12  零界寒冰  阅读(233)  评论(0编辑  收藏  举报