1.冒泡排序介绍

百度百科:

1.冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
2.它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
3.这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

示意图:

菜鸟教程冒泡排序示意图:
图来自菜鸟教程
整体思路:
要从小到大排序
1.有n个数需要被排序;假设先选取第0个位置的数字和让其和后一位的数进行比较;
2.如果比较时发现当前数比后一个数大(即比较时,出现不符合我们规则的顺序),
交换两数;
3.然后选第1个位置的数字,继续遍历,一轮后,即可找出一个最大数;(即最后一位已经到达其应在位置;)
最后一个数已经不需要参与后面的比较了;
4.继续遍历,则每轮比较后,最后一个数就会到达其应到位置;
5.每轮能找出一个最大的数,则最多仅需n-1轮即可全部排序完成;因为其余数排序好后,最后一个数不用在找自己的位置了;(i表示外层for循环表示轮数)
6.每轮选中的数下标为j,从0开始;
因为选中的数和后一个比较,最后一个不用选中,所以j的上限 -1;
又因为每过1轮,最后一个数就会被定下来,所以每轮j的上限 -i;

2.代码实现

2.1 基础冒泡排序

代码如下:

package main
import (
	"fmt"
)
func main() {

	//1.定义测试数组
	// var intArr = [...]int {10,5,11,9,0} //test01
	var intArr = [...]int {1,0,2,3} //test02
	
	//2.输出排序前数组;
	fmt.Println("排序前:",intArr)

	/*整体思路: 
	3.从小到大排序
	3.1有n个数需要被排序;假设先选取第0个位置的数字和让其和后一位的数进行比较;
	3.2如果比较时发现当前数比后一个数大(即比较时,出现不符合我们规则的顺序),
		交换两数;
	3.3然后选第1个位置的数字,继续遍历,一轮后,即可找出一个最大数;(即最后一位已经到达其应在位置;)
		最后一个数已经不需要参与后面的比较了;
	3.4继续遍历,则每轮比较后,最后一个数就会到达其应到位置;
	3.5每轮能找出一个最大的数,则最多仅需n-1轮即可全部排序完成;因为其余数排序好后,
		最后一个数不用在找自己的位置了;(i表示外层for循环表示轮数)
	3.6每轮选中的数下标为j,从0开始;
		因为选中的数和后一个比较,最后一个不用选中,所以j的上限 -1;
		又因为每过1轮,最后一个数就会被定下来,所以每轮j的上限 -i;
	 */
	for i:=0;i< len(intArr)-1;i++{
		for j:=0;j< len(intArr)-1-i;j++{

			if intArr[j+1] < intArr[j]{
				temp := intArr[j+1]
				intArr[j+1] = intArr[j]
				intArr[j] =temp
			}

		}
		fmt.Printf("第%v轮冒泡排序后:%v\n",i+1,intArr)
		
	}
	
}

2.2 优化版冒泡排序

如果一轮遍历比较后,没有发生过交换,则当前每一个数都比他后面的数小;
即当前数组已有序;则立即可停止排序;

代码如下:

package main
import (
	"fmt"
)
func main() {

	//1.定义测试数组
	var intArr = [...]int {10,5,11,9,0} //test01
	// var intArr = [...]int {1,0,2,3} //test02
	
	//2.输出排序前数组;
	fmt.Println("排序前:",intArr)

	/* 3.从小到大排序
	3.1有n个数需要被排序;假设先选取第0个位置的数字和让其和后一位的数进行比较;
	3.2如果比较时发现当前数比后一个数大(即比较时,出现不符合我们规则的顺序),
		交换两数;
	3.3然后选第1个位置的数字,继续遍历,一轮后,即可找出一个最大数;(即最后一位已经到达其应在位置;)
		最后一个数已经不需要参与后面的比较了;
	3.4继续遍历,则每轮比较后,最后一个数就会到达其应到位置;
	3.5每轮能找出一个最大的数,则最多仅需n-1轮即可全部排序完成;因为其余数排序好后,
		最后一个数不用在找自己的位置了;(i表示外层for循环表示轮数)
	3.6每轮选中的数下标为j,从0开始;
		因为选中的数和后一个比较,最后一个不用选中,所以j的上限 -1;
		又因为每过1轮,最后一个数就会被定下来,所以每轮j的上限 -i;
	 */
	for i:=0;i< len(intArr)-1;i++{

		//4.如果一轮遍历比较后,没有发生过交换,则当前每一个数都比他后面的数小,
		//即当前数组已有序;则立即可停止排序;

		//定义 is_changed ,记录每轮发生过交换;
		var is_changed bool 
		for j:=0;j< len(intArr)-1-i;j++{

			if intArr[j+1] < intArr[j]{
				//如果顺序不对,则发生交换,字段变为 true;
				is_changed = true
				//交换两数位置;
				intArr[j] = intArr[j+1] ^ intArr[j]
				intArr[j+1] = intArr[j+1] ^ intArr[j]
				intArr[j] = intArr[j+1] ^ intArr[j]
			}

		}
		fmt.Printf("经过%v轮遍历;冒泡排序后结果为:%v\n",i+1,intArr)
		//如果一整轮没交换过,则已经有序;退出排序;
		if is_changed == false {
			fmt.Printf("现在已经有序,直接停止;\n")
			break;
		}

	}
	
}
3.结果测试

test01:

测试数据:{10,5,11,9,0}
测试结果:
在这里插入图片描述

test02:

测试数据:{1,0,2,3}
测试结果:
在这里插入图片描述