一 冒泡排序

1.1 冒泡排序概念
冒泡排序(Bubble Sort)是一种交换排序,基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序记录位置。
假设要对无序数列{2,3,4,5,6,7,8,1}排序:
冒泡排序规律:每一轮排序两两比较都会把最大的值移动到最后一位,最大值就像在不断的冒泡一样。
1.2 冒泡算法
func BubbleSort(arr []int) {
	if arr == nil || len(arr) < 2 {
		fmt.Println("数组不满足要求")
		return
	}
	// 外层循环:确定扫描的次数
	for i := 1; i <= len(arr) - 1; i++ {
		// 内层循环:一轮扫描内,两两比较,进行交换
		for j := 0; j <= len(arr) - 1 - i; j++ {	 // - i 的原因是后面的元素已经被排序过
			if arr[j] > arr[j + 1] {
				temp := arr[j]
				arr[j] = arr[j + 1]
				arr[j + 1] = temp
			}
		}
	}
}
1.3 冒泡算法优化
如果要排序的数据序列已经完全有序了,那么冒泡算法仍然会按照两两比较策略继续走下去,这是不能容忍的,我们可以先记录该数据序列是否有序,只要内层循环没有发生交换,就证明整个数组现在已经有序,无需外层循环再次排序!
func BubbleSort(arr []int) {
	if arr == nil || len(arr) < 2 {
		fmt.Println("数组不满足要求")
		return
	}
	isSorted := false
	for i := 1; i <= len(arr)-1; i++ {
		isSorted = true
		for j := 0; j < len(arr)-1-i; j++ {
			if arr[j] > arr[j+1] {
				temp := arr[j+1]
				arr[j+1] = arr[j]
				arr[j] = temp
				isSorted = false
			}
		}
		if isSorted {
			break
		}
	}
}
1.4 冒泡排序优化二
显然数据的完全有序概率是很低的,但是数据局部有序的情况概率还是很高的。如果如果最后几个元素都已经是排好的,那么这几个局部有序的数据就无需进行冒泡排序了,如:arr := []int{3, 2, 4, 1, 6, 0, 5, 7, 8, 9}。在1.3优化一的基础上,我们可以通过记录最后一次排序比较的索引,来继续优化:
func BubbleSort(arr []int) {
	if arr == nil || len(arr) < 2 {
		fmt.Println("数组不满足要求")
		return
	}
	isSorted := false
	sortIndex := len(arr) - 1 - 1
	lastIndex := 0 // 记录最后一次交换的位置
	for i := 1; i <= len(arr)-1; i++ {
		isSorted = true
		for j := 0; j <= sortIndex; j++ {
			if arr[j] > arr[j+1] {			// 不能加入等号,这样会造成不稳定
				temp := arr[j]
				arr[j] = arr[j+1]
				arr[j+1] = temp
				isSorted = false
				lastIndex = j
			}
		}
		if isSorted {
			break
		}
		sortIndex = lastIndex
	}
}
二 冒泡排序复杂度分析
- 最好情况:数据本身是有序的,那么其时间复杂度应该是O(n)
- 最坏情况:表中所有的元素都是逆序的,时间复杂度为O(n^2)。
三 扩展:鸡尾酒排序
冒泡排序的每一轮都是从左到右比较,进行单向的位置交换。鸡尾酒排序则可以让比较和交换的过程是双向的。
对1.1图中的序列进行冒泡排序会造成大量浪费,鸡尾酒排序则很容易实现:
也就是说鸡尾酒的排序过程像钟摆一样,奇数轮和偶数轮来回排序,第1轮从左往右,第2轮从右往左,第3轮再从左往右,直到有一轮排序时没有发生交换,则退出循环。
我们也不难发现:当一个无需数列中,大多元素都有序的时,使用鸡尾酒排序则能达到很好的效果。














![[Leetcode 47][Medium]-全排列 II-回溯(全排列问题)](https://i-blog.csdnimg.cn/direct/bc48911838ec43c5a058ea11f88d16ce.png)




