Go语言数据结构和算法(二十)归并排序

36 阅读2分钟

归并排序是基于分治算法最流行的的排序算法之一.一个问题被分成多个子问题.每个子问题都是单独解决的.最后.将子问题组合起来形成最终解决方案.

1.使用场景:

大型数据集:

归并排序对于大型数据集很有效.因为其他排序算法的开销对性能的影响相对显著.

外部排序:

其中数据集无法进入主内存.必须通过读取和写入外部存储设备(磁盘)进行排序.

并行处理:

归并排序算法易于并行化.是并行处理场景下大型数据集的最佳选择.

2.实现:

2.1方法:

	if len(slice) < 2 {
		return slice
	}

	mid := (len(slice)) / 2
	return Merge(MergeSort(slice[:mid]), MergeSort(slice[mid:]))
}

func Merge(left, right []int) []int {
	size, i, j := len(left)+len(right), 0, 0
	slice := make([]int, size, size)
	for k := 0; k < size; k++ {
		if i > len(left)-1 && j <= len(right)-1 {
			slice[k] = right[j]
			j++
		} else if j > len(right)-1 && i <= len(left)-1 {
			slice[k] = left[i]
			i++
		} else if left[i] < right[j] {
			slice[k] = left[i]
			i++
		} else {
			slice[k] = right[j]
			j++
		}
	}
	return slice
}

2.2main方法:

	array := []int{33, 23, 56, 7, 8, 18, 99, 28}
	res := data.MergeSort(array)
	fmt.Println(res)
}

3.实战:

3.1方法:

	if len(array) <= 1 {
		return array
	}
	mid := len(array) / 2
	left := MergeSort1(array[:mid])
	right := MergeSort1(array[mid:])
	return merge1(left, right)
}

func merge1(left, right []int) []int {
	ret := make([]int, 0, len(left)+len(right))
	for len(left) > 0 || len(right) > 0 {
		if len(left) == 0 {
			return append(ret, right...)
		}
		if len(right) == 0 {
			return append(ret, left...)
		}
		if left[0] < right[0] {
			ret = append(ret, left[0])
			left = left[1:]
		} else {
			ret = append(ret, right[0])
			right = right[1:]
		}
	}
	return ret
}

3.2main方法:

	array := []int{9, 88, 6, 36, 78, 2}
	res := data.MergeSort1(array)
	fmt.Println(res)
}

4.实战:

4.1方法:

	Data int
	Next *ListNode
}

func SortList(head *ListNode) *ListNode {
	length := 0
	cur := head
	for cur != nil {
		length++
		cur = cur.Next
	}

	if length <= 1 {
		return head
	}

	middleNode := middleNode(head)
	cur = middleNode.Next
	middleNode.Next = nil
	middleNode = cur
	left := SortList(head)
	right := SortList(middleNode)
	return mergeTwoLists(left, right)
}

func mergeTwoLists(left *ListNode, right *ListNode) *ListNode {
	if left == nil {
		return right
	}

	if right == nil {
		return left
	}

	if left.Data < right.Data {
		left.Next = mergeTwoLists(left.Next, right)
		return left
	}
	right.Next = mergeTwoLists(left, right.Next)
	return right
}

func middleNode(head *ListNode) *ListNode {
	if head == nil || head.Next == nil {
		return head
	}
	list1 := head
	list2 := head
	if list2.Next != nil && list2.Next.Next != nil {
		list1 = list1.Next
		list2 = list2.Next.Next
	}
	return list1
}

4.2main方法:

	listNode := &data.ListNode{8, &data.ListNode{18, &data.ListNode{6, &data.ListNode{3, nil}}}}
	res := data.SortList(listNode)
	fmt.Println(res.Data)
	fmt.Println(res.Next.Data)
	fmt.Println(res.Next.Next.Data)
	fmt.Println(res.Next.Next.Next.Data)
}

而立不惑知天命.

如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路