image.png

是不是稳定的定义就是看具有相同字段的相对位置是不是遭到破坏 稳定的排序算法:简单的理解就是,能保证排序前2个相等的数所在序列的前后相对位置顺序 和排序后它们两个的前后位置顺序相同。如果A1 = A2,A1原来在位置前面,排序后A1还是保持在A2位置前。 不稳定的排序算法:排序前后在序列中的相对位置发生变化。

冒泡排序

平均时间复杂度是O(n²):逆序排列
最好情况是O(n):当输入的数据已经有序时,只需遍历一遍用于确认数据已有序
最坏情况是O(n²)
空间复杂度是O(1)
稳定性是稳定的:因为每次比较后如果两个相邻元素相等我们并不会将他们交换,
所以冒泡不会改变相同元素的下标,所以冒泡排序是一个稳定的排序。
image.png
只遍历一次
image.png

选择排序

解法:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
平均时间复杂度是O(n²)
最好情况是O(n²)
最坏情况是O(n²)
空间复杂度是O(1)
稳定性是不稳定的:举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,
那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法

  1. func SelectSort(arr []int) {
  2. n := len(arr)
  3. for i := 0; i < n; i++ {
  4. minIndex := i
  5. for j := i+1; j < n; j++ {
  6. if arr[j] < arr[minIndex] {
  7. minIndex = j
  8. }
  9. }
  10. if minIndex != i {
  11. arr[minIndex], arr[i] = arr[i], arr[minIndex]
  12. }
  13. }

插入排序

从第一个元素开始,该元素可以认为已经被排序,取出下一个元素,在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于新元素,将该元素移到下一位置,重复步骤,直到找到已排序的元素小于或者等于新元素的位置。
平均时间复杂度是O(n²)
最好情况是O(n):当输入的数据已经有序时,只需遍历一遍用于确认数据已有序
最坏情况是O(n²):完全逆序
空间复杂度是O(1)
稳定性是稳定的

  1. func InsertSort(arr []int) {
  2. n := len(arr)
  3. for i := 0; i < n-1; i++ {
  4. if arr[i+1] < arr[i] {
  5. for j := i+1; j > 0 && arr[j] < arr[j-1]; j-- {
  6. arr[j], arr[j-1] = arr[j-1], arr[j]
  7. }
  8. }
  9. }
  10. }

希尔排序

基于插入排序改进的,插入排序每次只能将数据移动一位。希尔排序是一种分组插入方法
第一步:分组。按一定的间隔分组,然后组内排序(尽量间隔取总长的一半,这样每组就是两个元素)
第二步:重新设置间隔分组,继续组内排序
image.png
平均时间复杂度:T(n) = O(nlogn)
最坏时间复杂度:T(n) = O(nlog²n)
最坏时间复杂度:T(n) = O(nlog²n)
空间复杂度: O(1)
稳定性: 不稳定,由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,
但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所
以shell排序是不稳定的。

  1. func ShellSort(arr []int) {
  2. n := len(arr)
  3. increment := n
  4. for true {
  5. increment = increment/3 + 1
  6. for i := 0; i < increment; i++ {
  7. for j := i + increment; j < n; j+=increment {
  8. for k := j; k > i && arr[j] < arr[j-increment]; k-=increment {
  9. arr[k], arr[k-increment] = arr[k-increment], arr[k]
  10. }
  11. }
  12. }
  13. if increment == 1{
  14. break
  15. }
  16. }
  17. }

二分查找

  1. func BinarySearch(arr []int, val int) int {
  2. l, r := 0, len(arr)-1
  3. for l <= r {
  4. mid := (l + r)/2
  5. tmp := arr[mid]
  6. if tmp == val {
  7. return mid
  8. } else if val < tmp {
  9. r = mid - 1
  10. } else {
  11. l = mid + 1
  12. }
  13. }
  14. return -1
  15. }