1.选择排序
- 从数组的第一个元素开始,找到未排序元素中最小的元素。
- 将最小的元素交换到已排序的部分的最前面。
- 重复上述步骤
fun selectSort(array: Array<Int>) {
val n = array.size
for (i in 0 until n) {
var min = i
for (j in i + 1 until n) {
if (array[min] > array[j]) {
min = j
}
}
if(min != i){
val temp = array[min]
array[min] = array[i]
array[i] = temp
}
}
array.forEach {
print(it)
}
}
2.冒泡排序
- 从数组的第一个元素开始,比较相邻的两个元素。
- 如果第一个元素比第二个元素大,则交换它们的位置。
- 重复上述步骤
- 优化:可以使用一个标志来表示是否有元素交换过位置。如果没有元素交换过位置,则说明数组已经排序好了,可以提前退出循环。
fun bubbleSort(array: Array<Int>){
val n = array.size
for(i in 0 until n-1){
for(j in 0 until n-i-1){
if(array[j+1]<array[j]){
val temp = array[j+1]
array[j+1] = array[j]
array[j] = temp
}
}
}
array.forEach {
print(it)
}
}
选择排序与冒泡排序区别:
- 稳定性:冒泡排序是一种稳定的排序算法。这意味着在排序过程中,具有相同值的元素会保持它们原来的顺序。而选择排序则是一种不稳定的排序算法,它可能会改变具有相同值的元素的原始顺序。
- 排序方法:冒泡排序是通过比较相邻的元素,并在必要时交换它们的位置来进行排序的。它重复这个过程,直到整个列表都已排序。另一方面,选择排序则通过在未排序的部分中找到最小(或最大)的元素,然后将其与该部分的起始元素交换位置。这个过程会持续进行,直到整个列表都已排序。
- 交换成本:在冒泡排序中,元素之间的交换是相邻的,这意味着每次交换都只需要改变两个元素的位置。然而,在选择排序中,元素可能会与列表中的任何元素进行交换,这可能导致更多的数据移动和更高的交换成本。
- 时间复杂度:在最坏的情况下(即列表是逆序的),两种算法的时间复杂度都是O(n^2),其中n是列表中的元素数量。然而,在最好的情况下(即列表已经是有序的),冒泡排序的时间复杂度是O(n),因为它只需要遍历一次列表就可以确认它已经是有序的。而选择排序的时间复杂度始终是O(n^2),因为它必须执行n-1次扫描,每次扫描都涉及比较和可能的交换。
- 空间复杂度:两者都只需要一个额外的空间来存储临时数据(例如,用于交换的元素),因此它们的空间复杂度都是O(1)。
总的来说,冒泡排序和选择排序各有其特点。冒泡排序是稳定的,且在某些情况下可能具有较高的效率(如当列表已经部分排序时)。而选择排序则更注重于快速找到最小(或最大)的元素,并将其放置到正确的位置。在选择使用哪种算法时,应根据具体的应用场景和需求进行决策。