[算法初步]之插入排序

##1 描述

插入算法是生活中比较常用的算法,这个算法可以说所有人都用过,连小学生都会。只不过你平时用的时候没有意识到这个算法罢了。
比如说斗地主,这个大家都玩过吧。这个抓牌的过程其实就是一种插入排序的实现。

(当然可能略有些不同,斗地主是三个人抓牌,换排序肯可能就是你一个人抓一堆牌了)。

##2 场景

首先来设定一个抓牌的场景,我们用1代表A,11代替J,13代替K。很明显,牌堆里面都是未排好序的,而抓牌后在你左手中的都是排序好的牌。
所以当前牌堆里面的牌是

* 左手:[] 牌堆:[3, 5, 1, 7, 6, 2, 11, 13, 4]。

ok,下面摸第一张牌,是一张3,放到左手,第一张牌本来就是排序好的,所以不用动了。

* 左手: [3] 牌堆:[5, 1, 7, 6, 2, 11, 13, 4]

继续摸第二张,右手抓了个5,还是比3大,直接放到3后面。

* 左手: [3,5] 牌堆:[1, 7, 6, 2, 11, 13, 4]

继续摸第二张,右手抓了个A,明显比3和5小需要排到3和5前面去,因此将3和5往右移一位,给A空出位置。然后将A插入大牌左手的牌堆空出的位置里。

* 左手: [空位,3 ,5] 牌堆:[ 7, 6, 2, 11, 13, 4] 右手[1]
* 左手: [1,3,5] 牌堆:[7, 6, 2, 11, 13, 4]

然后继续从牌堆里面拿牌,知道牌堆里面所有的牌都抓到左手中。

* 左手:[1, 2, 3, 4, 5, 6, 7, 11, 13] 牌堆:[]

##3 go语言代码

下面用go语言对上面的算法进行实现。

和上面有些小不同:所有的数字其实都放在一个数组中排序,而且第一个数字默认已经是排序好的。

	package main
	 
	import "fmt"
	
	/*
	 * [插入排序]场景:
	 * 1 左边牌堆认为已经排好序(i),右边为未排序的牌(N-i)。
	 * 2 从右边取出下一张牌,在左边牌堆又后向前扫描比较。
	 * 3 比右边要插入牌大的话,则此牌往下移动一个位置。
	 * 4 重复步骤3,直到找到为新插入的牌调好位置
	 * 6 将手上的牌插到空留出的位置上。
	 * 7 重复步骤2,直到右边所有的牌都排序完成
	 */
	
	func sort(data *[9]int) {
	
	    var temp int
	    var i, j int
	    // 从右边堆取出牌到左边堆
	    for i = 1; i < len(data); i++ {
	        temp = data[i]
	
	        // 插入一张的操作,判断i-1张牌,比其的大后移,
	        for j = i - 1; j >= 0; j-- {
	            if data[j] > temp {
	                data[j+1] = data[j]
	            } else {
	                break
	            }
	        }
	
	        // 插入牌到移动后牌空出的位置上,在判断出的j位置之后
	        data[j+1] = temp
	    }
	}
	
	/**
	 * @param args
	 */
	func main() {
	    data := [9]int{3, 5 , 1, 7, 6, 2, 11, 13, 4}
	    sort(&data)
	    for i := 0; i < len(data); i++ {
	        fmt.Print(data[i])
	        fmt.Print(",")
	    }
	}
posted @ 2013-04-15 15:31  零界寒冰  阅读(161)  评论(0编辑  收藏  举报