经典排序算法 | 青训营笔记

76 阅读2分钟

课程视频里的三个经典排序算法:插入排序、快速排序、堆排序。

插入排序

插入排序是一种简单的排序方法,通过将待排序的元素插入到已经排好序的有序表中,实现一个新元素排序。其基本思想是外层循环从 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)  
    }  
}