冒泡排序
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。假设长度为n的数组arr,要按照从小到大排序。则冒泡排序的具体过程可以描述为:首先从数组的第一个元素开始到数组最后一个元素为止,对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,则交换这两个元素在数组中的位置。这样操作后数组最右端的元素即为该数组中所有元素的最大值。接着对该数组除最右端的n-1个元素进行同样的操作,再接着对剩下的n-2个元素做同样的操作,直到整个数组有序排列。
步骤:
- 比较两个元素,如果前面元素的值比后面元素的值大,则交换位置;
- 对每一对相邻的元素都进行比较,例如从第一对相邻的元素开始比较,比较到最后一对,经过这一轮的比较后理论上最后的元素是最大的;
- 对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
需求:假如有一个[10,1,-99,189]的一个数组,让你对这个数组从小到大进行排序
详细排序过程:
下面是第一轮比较:
1-1:根据步骤1,2,对每一个相邻的元素进行排序,从第一对即:10,1开始,比较后你会发现10比1大,因此需要交换彼此的位置,交换位置后的数组:[1,10,-99,189];
1-2:继续比较第二对元素:10,-99,比较后你会发现10比-99大,因此需要交换彼此位置,交换后数组:[1,-99,10,189];
1-3:继续比较第三对元素:10,189,比较后你会发现10比189小,因此不需要交换彼此位置,因此数组还是[1,-99,10,189],而且此时已经每一个元素都已经对比了一遍,因此这一轮对比结束,得出最大的元素是189;
下面是第二轮比较:
经过上一轮的比较,此时的数组元素之间的顺序已经有所修改,已经被修改为:[1,-99,10,189]
2-1:从第一对即:1,-99开始,比较后你会发现1比-99大,因此需要交换彼此的位置,交换后的数组:[-99,1,10,189];
2-2:继续比较第二对元素:1,10,比较后你会发现1比10小,因此不需要交换彼此位置,数组还是:[-99,1,10,189];
由于189这个元素已经在第一轮的对比过程中得出是最大得元素了,再次比较没有任务意义,一次第二轮比较只需要比较两次即可;
下面是第三轮比较:
经过第二轮的比较,此时的数组元素之间的顺序已经有所修改,已经被修改为:[-99,1,10,189];
3-1:从第一对即:-99,1开始,比较后你会发现-99比1大,因此不需要交换彼此位置,数组还是:[-99,1,10,189];
由于值为10元素的元素在第二轮的对比中已经被排序,因此再次比较没有任何意义,因此本轮比较只需要比较一次,本轮比较结束;
总结:
- 由上面的排序过程可知,每一轮的对比里面还涉及对次对比,因此涉及到两次for循环,每一次的
- 因为两次for循环,因此时间复杂度为O(n2)
代码实现:
package main
import "fmt"
func main() {
target := []int{10, 1, -99, 189}
bubbleSort(target)
fmt.Println(target)
}
func bubbleSort(target []int) {
length := len(target)
for i := 0; i < length-1; i++ {
for j := 0; j < length-i-1; j++ { //每经过一次外层循环,即每经过一轮的对比都能比较出一个当前最大的元素,那么下一轮的对比次数就需要减少一次,一次需要 length - i;又因为自身不需要对比,因此还需减掉本身,即减1
if target[j] > target[j+1] {
target[j], target[j+1] = target[j+1], target[j]
}
}
}
}