1、概述
冒泡排序是一种简单的算法,是指重复遍历需要排序的元素列,一次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母a~z等)错误就把他们交换过来,遍历的目的是重复的进行指导没有相邻元素需要交换 即该元素列已经排序完成。
2、算法原理
1)比较相邻的元素,如果第一个比第二个大,就交换他们两个
2)对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,在这一点,最后的元素会是最大的数
3)针对所有的元素重复以上的步骤,除了最后一个
4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
3、举例
需要对 1 4 6 2 8 这5个数按照从大到小的顺序进行排序
1)首先,对第一位和第二位进行比较,明显 1<4,所以交换 1 和 4 的位置
2)继续比较第二位和第三位,发现 1<6,所以交换 1 和 6 的位置
3)继续比较第三位和第四位,1<2 ,交换 1 和 2 的位置
4)最后比较 第四位和第五位 ,1<8 ,交换 1 和 8 的位置
经过上面一轮的比较,我们发现,1是最小的,且放在了最后。
下面是1上浮的过程,为什么说是上浮?是由于数字是存储在数组中的,在swift中,数组是先进后出的,栈一般在swift的实现都是通过数组。并且1的上浮过程像水泡从水底上浮到水面,所以 算法 叫 冒泡排序
剩余的元素依次按照上述操作继续比较,把最小的2放在倒数第二位,以此类推,最大的8位于首位
4、算法实现
1)一般实现
按照冒泡的原理,一般实现为
func bubbleSort(_ array : [Int]){
var list = array
//记录循环次数
var count = 0
for i in 0..<list.count {
count = i
for j in i+1..<list.count{
if list[i] > list [j] {
//交换方式1
// let tmp = list[j]
// list[j] = list[i]
// list[i] = tmp
//交换方式2
list.swapAt(i, j)
//交换方式4
// (list[i], list[j]) = (list[j], list[i])
//交换方式5
// swap(&list[i], &list[j])
}
}
}
print(list)
print("count: ",count)
}
注:数据的交换过程在swift中有3种
1)定义变量交换
let tmp = list[j]
list[j] = list[i]
list[i] = tmp
2)数组自带的交换方法
list.swapAt(i, j)
3)使用元祖的交换方法
(list[i], list[j]) = (list[j], list[I])
4)也可以自定义swap方法
5)swift自带的交换方法
swap(&list[i], &list[j])
2)外层优化
当发现在某一趟排序中没有发生交换,则说明排序已经完成,所以可以在此趟排序后结束排序,在每趟排序前设置flag,当其未发生变化时,终止算法
func bubbleSort1(_ array : [Int]){
var list = array
//记录循环次数
var count = 0
for i in 0..<list.count {
var flag = true
count = i
for j in i+1..<list.count{
if list[i] > list [j] {
list.swapAt(i, j)
flag = false
}
}
if flag {
break
}
}
print(list)
print("count: ",count)
}
3)内层优化
每趟排序中,最后一次发生交换的位置后面的数据均以有序,所以可以记住最后一次交换的位置来减少排序的趟数
func bubbleSort2(_ array : [Int]){
var list = array
//swap变量用来标记循环里最后一次交换的位置
var swap = 0
var k = list.count - 1
//记录循环次数
var count = 0
for i in 0..<list.count {
var flag = true
count = i
for j in 0..<k{
if list[j] > list [j+1] {
list.swapAt(j, j+1)
flag = false
swap = j
}
}
k = swap
if flag {
break
}
}
print(list)
print("count: ",count)
}
4)方法的使用
print("冒泡")
let array = [1,3,6,9,0,5,2,4,8,7]
SortSummary.bubbleSort(array)
SortSummary.bubbleSort1(array)
SortSummary.bubbleSort2(array)
print("\n")
运行结果:
冒泡
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
count: 9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
count: 9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
count: 4
注:可以从执行的循环次数看出,内层优化次数减少了
5、时间复杂度
1)最好的情况下 即待排序的数组本身是有序的,比较次数为n-1,没有数据交换,即O(n)
2)最坏的情况下 即待排序的数组是完全逆序的,比较次数为n*(n-1)/2,即O(n^2)
3)平均复杂度 O(n^2)
注:排序的具体实现代码在 SortSummary.swift 文件里 调用是在 ViewController.swift