课程视频里的三个经典排序算法:插入排序、快速排序、堆排序。
插入排序
插入排序是一种简单的排序方法,通过将待排序的元素插入到已经排好序的有序表中,实现一个新元素排序。其基本思想是外层循环从 0 开始遍历整个序列,内层循环在当前元素前插入位置查找并移动。外层循环依次将已经排好序的元素插入到序列的起始位置,内层循环将当前元素插入到前一个元素之前的位置。
时间复杂度
- Best: O(n)
- Avg: O(n^2)
- Worst: O(n^2)
代码实现
func InsertionSort(arr []int) {
length := len(arr)
for i := 1; i < length; i++ {
for j := i - 1; j >= 0; j-- {
if arr[j] > arr[j+1] {
temp := arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
} else {
break
}
}
}
}
快速排序
快速排序通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
时间复杂度
- Best: O(n*logn)
- Avg: O(n*logn)
- Worst: O(n^2)
代码实现
func QuickSort(arr []int, left int, right int) {
if left < right {
i := left
j := right
x := arr[left]
for i < j {
for i < j && arr[j] >= x {
j--
}
if i < j {
arr[i] = arr[j]
i++
}
for i < j && arr[j] < x {
i++
}
if i < j {
arr[j] = arr[i]
j--
}
}
arr[i] = x
QuickSort(arr, left, i-1)
QuickSort(arr, i+1, right)
}
}
堆排序
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,将待排序序列构成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点,将其与末尾元素进行交换,此时末尾就是最大值,然后将剩余n-1个元素重新构造成一个堆,就会得到n个元素的次小值,如此反复执行,便能得到一个有序序列。
时间复杂度
- Best: O(n*logn)
- Avg: O(n*logn)
- Worst: O(n*logn)
代码实现
package HeapSort
func swap(a *int, b *int) {
temp := *a
*a = *b
*b = temp
}
func maxHeapify(arr []int, start int, end int) {
dad := start
son := dad*2 + 1
for son <= end {
if son+1 <= end && arr[son] < arr[son+1] {
//先比较两个子节点大小,选择最大的
son++
}
if arr[dad] > arr[son] {
return
} else {
swap(&arr[dad], &arr[son])
dad = son
son = dad*2 + 1
}
}
}
func HeapSort(arr []int, len int) {
//初始化,i从最後一个父节点开始调整
for i := len/2 - 1; i >= 0; i-- {
maxHeapify(arr, i, len-1)
}
//先将第一个元素和已排好元素前一位做交换,再重新调整,直到排序完毕
for i := len - 1; i > 0; i-- {
swap(&arr[0], &arr[i])
maxHeapify(arr, 0, i-1)
}
}