6种排序算法(Golang)

120 阅读1分钟

选择排序

func SelectSort(arr []int) {
   n := len(arr)
   for i := 0; i < n; i++ {
      minIndex := i
      for j := i + 1; j < n; j++ {
         if arr[j] < arr[minIndex] {
            minIndex = j
         }
      }
      swap(arr, minIndex, i)
   }
}

func swap(arr []int, a, b int) {
   arr[a], arr[b] = arr[b], arr[a]
}

冒泡排序

func BubbleSort(arr []int) {
   for j := len(arr) - 1; j > 0; j-- {
      for i := 0; i < j; i++ {
         if arr[i] > arr[i+1] {
            swap(&arr, i, i+1)
         }
      }
   }
}

func swap(arr *[]int, a, b int) {
   (*arr)[a], (*arr)[b] = (*arr)[b], (*arr)[a]
}

插入排序

func InsertionSort(arr []int) {
   for i := 1; i < len(arr); i++ {
      for j := i - 1; j >= 0 && arr[j] > arr[j+1]; j-- {
         swag(arr, j, j+1)
      }
   }
}

func swag(arr []int, a, b int) {
   arr[a], arr[b] = arr[b], arr[a]
}

并归排序

func merge(arr []int, left, right, mid int) {
   var temp []int
   p1 := left
   p2 := mid + 1

   for p1 <= mid && p2 <= right {
      if arr[p1] <= arr[p2] {
         temp = append(temp, arr[p1])
         p1++
      } else {
         temp = append(temp, arr[p2])
         p2++
      }
   }

   for p1 <= mid {
      temp = append(temp, arr[p1])
      p1++
   }

   for p2 <= right {
      temp = append(temp, arr[p2])
      p2++
   }

   for i, val := range temp {
      arr[left+i] = val
   }

}

func mergeSort(arr []int, left, right int) {
   if left < right {
      mid := (left + right) >> 1
      mergeSort(arr, left, mid)
      mergeSort(arr, mid+1, right)
      merge(arr, left, right, mid)
   }
}

快速排序

func quickSort(nums []int, l, r int) { //[l,r]
   if l < r {
      m := partition(nums, l, r)
      quickSort(nums, l, m-1)
      quickSort(nums, m+1, r)
   }

}

func partition(nums []int, l int, r int) int {
   key := nums[r]
   i := l
   j := l
   for j < r {
      if nums[j] < key {
         nums[i], nums[j] = nums[j], nums[i]
         i++
      }
      j++
   }
   nums[i], nums[r] = nums[r], nums[i]
   return i
}

堆排序

func heapInsert(arr []int, index int) {
   for {
      if arr[index] <= arr[(index-1)/2] {
         break
      } else {
         arr[index], arr[(index-1)/2] = arr[(index-1)/2], arr[index]
         index = (index - 1) / 2
      }
   }
}

// 判断index处的值能否往下移动
// O(logN)
func heapify(arr []int, index int, heapSize int) {
   left := index*2 + 1 //左孩子index
   for left <= heapSize {
      var largest int

      if left+1 < heapSize && arr[left+1] > arr[left] { //右孩子存在并且右孩子大于左孩子
         largest = left + 1
      } else {
         largest = left
      }

      if arr[largest] < arr[index] { //父亲给较大孩子谁大谁给largest
         largest = index
      }

      if largest == index { //判断是否继续往下走
         break
      }

      arr[largest], arr[index] = arr[index], arr[largest]
      index = largest
      left = index*2 + 1
   }
}

func heapSort(arr []int) {
   if len(arr) == 0 || len(arr) < 2 {
      return
   }

   //方法1
   for i := 0; i < len(arr); i++ { //一个一个加入二叉树形成大根堆 0(N)
      heapInsert(arr, i)
   }

   /*
      //方法2
      for i := len(arr) - 1; i >= 0; i-- { //子树一个一个形成大根堆 更快
         heapify(arr, i, len(arr))
      }
   */

   heapSize := len(arr) - 1
   arr[0], arr[heapSize] = arr[heapSize], arr[0]
   heapSize--

   for heapSize > 0 {
      heapify(arr, 0, heapSize)
      arr[0], arr[heapSize] = arr[heapSize], arr[0]
      heapSize--
   }
}
时间复杂度空间复杂度稳定性
选择排序O(N^2)O(1)N
冒泡排序O(N^2)O(1)Y
插入排序O(N^2)O(1)Y
并归排序O(NlogN)O(N)Y
快速排序O(NlogN)O(logN)N
堆排序O(NlogN)O(1)N