[算法初步]之归并排序 ##1 说明 归并排序 ##2 场景 我一直觉得算法是在赌博中发明出来,比如这个归并算法,我们可以通过打麻将来模拟这个场景。 一般打麻将抓牌,都是先抓好,等牌都抓齐了牌之后才会进行整理。比如我们手里抓到了从一万到九万,一手未排序的万子。 * [3, 5 , 1, 7, 6, 2, 8, 9, 4] 麻将这玩意一般比较大,一手一堆放不下,所以我们分为2堆来整理。 * [[3, 5 , 1, 7][ 6, 2, 8, 9, 4]] 干脆分到底好了,继续分成2张为一堆的。 * [[[3, 5] [1, 7]] [[6, 2][ 8, 9] 4]]] 继续拆,知道拆分为一张为一堆 * [[[[3] [5]] [[1] [7]]] [[[6] [2]] [[8] [9]] [4]]]] 拆完牌了总要给拼起来啊。不然怎么出牌呢。好吧,我们就按每一堆来拼接,跟刚才拆牌逆着来。 在其他地方将刚才拆分的2堆牌拼好了再放回到原来的堆里,在这个拼接的过程中顺便把排序也给排好了。 第一次拼接 * [[[3, 5] [1, 7]] [[2, 6] [ 8, 9] 4]]] 继续拼接 * [[1, 3, 5, 7] [2, 4, 6, 8, 9]] 最后结果 * [1, 2, 3, 4, 5, 6, 7, 8, 9] 这个排序其实是一个将分治(分牌过程)和归并(拼牌过程)两个过程结合在一起。 ##3 go语言实现: package main import "fmt" /* * 分治法的思想 * 将问题递归分为一个个的小问题。 * 解决最小的问题 * 将结果进行归并 * [归并排序]场景: * 1 一堆N张散乱的麻将牌。 * 2 将这副牌分成相等的2堆,左边的为N/2,右边为N-N/2 * 3 继续递归分解,直到分到单一的一张牌 * 4 将分解后的单个牌按顺序循环归并,递归直到归并成一堆 */ /* * 归并方法 data 整个数组,归并左右两堆(【left,-middle】,【middle+1,-right】) left 归并左边数据的开始位置。 * midde 归并左边数据的结束位置。右边开始位置为middle+1 right 归并右边数据的结束位置 */ func merge(data *[9]int, left int, middle int, right int) { // 创建2个临时数组来存储左右两边的数据,长度分别为middle - left + 1,和right - middle length1 := middle - left + 1 length2 := right - middle leftTemp := make([]int, length1) rightTemp := make([]int, length2) // 复制数据到临时数组 i := 0 j := 0 for i = 0; i < length1; i++ { leftTemp[i] = data[left+i] } for j = 0; j < length2; j++ { rightTemp[j] = data[middle+1+j] } // 归并,第一次归并到一组数据已经为空的情况,第二次将剩下的一组数据复制到数据中。 k := left for i, j = 0, 0; i < length1 && j < length2; { if leftTemp[i] < rightTemp[j] { data[k] = leftTemp[i] k++ i++ } else { data[k] = rightTemp[j] k++ j++ } } if i == length1 { for j < length2 { data[k] = rightTemp[j] k++ j++ } } if j == length2 { for i < length1 { data[k] = leftTemp[i] k++ i++ } } } /* * 排序方法,先分治排序,然后合并 */ func sort(data *[9]int, left int, right int) { // left=right时候,长度为1 if left < right { middle := (left + right) / 2 // 分治,将date的【left--middel】来进行分解排序。最后返回的结果是全部排序好的。 sort(data, left, middle) // 分治,将date的【middel--right】来进行分解排序。最后返回的结果是全部排序好的。 sort(data, middle+1, right) // 组合,将数据的【left--middel】和【middel--right】进行归并 merge(data, left, middle, right) } } func main() { data := [9]int{3, 5, 1, 7, 6, 2, 8, 9, 4} sort(&data, 0, len(data)-1) for i := 0; i < len(data); i++ { fmt.Print(data[i], ",") } fmt.Println() }
转载于:https://www.cnblogs.com/sxt102400/archive/2013/04/16/3025213.html