面试必问的排序算法

复制代码
欢迎大家到我的博客浏览。排序算法 | YinKai's Blog

介绍

在面试中被问到排序算法,发现不能很好的描述出来,于是写一篇文章总结一下。常见的排序算法有 冒泡排序插入排序快速排序归并排序堆排序等。下面一一介绍。

1、冒泡排序 O(n^2)
算法思想:

共 n 个元素需要排序,通过比较相邻的两个元素,并将较大的元素放到后面,以此每一轮比较将乱序的元素中的最大的元素放到最后一个有序区间中。每一次遍历都能确定一个数在有序数组中的位置,且数组最后的一个区间中的数是有序的,直到所有数的位置都确定了,排序完成。

核心代码:
Go 复制代码
for i := 0; i < n-1; i++ {
    for j := 0; j < n-i-1; j++ {
        if arr[j] > arr[j+1] {
            // 交换 arr[j] 和 arr[j+1]
            arr[j], arr[j+1] = arr[j+1], arr[j]
        }
    }
}
2、插入排序 O(n^2)
算法思想:

遍历一遍整个数组,每次遍历将当前元素放到数组首部的有序序列中的合适位置,每次保证数组首部增加一个数,遍历 n - 1 次后,就可以保证整个数组的有序性。【合适的位置:往前找第一个小于当前数的位置,将其放在该数的后面,就说明当前数前面小于当前数,当前数后面大于当前数】

核心代码:
Go 复制代码
for i := 1; i < n; i++ {
    key := q[i] // 注意:在Go中切片的使用
    j := i - 1

    // 往前找第一个小于当前数的位置
    // 将其放在该数的后面,说明当前数前面小于当前数,当前数后面大于当前数
    for j >= 0 && q[j] > key {
        q[j+1] = q[j]
        j--
    }

    q[j+1] = key
}
3、快速排序 O(nlogn)
算法思想:

分而治之的一个思想,每次将整个数组分为两部分,然后保证左边是小于某个值的,右边是大于某个值的,这样在对两个部分采用同样的思想去划分,最后划分到区间中只有一个数了,就可以保证整个数组是有序的了。

核心代码:
Go 复制代码
func quickSort(q []int, l, r int) {
    if l >= r {
        return 
    }
​
    mid := (l + r) >> 1
    x := q[mid]
    i, j := l - 1, r + 1
    for i < j {
        for i ++; q[i] < x; i ++{}
        for j --; q[j] > x; j --{}
        if i < j {
            q[i], q[j] = q[j], q[i]
        }
    }
    quickSort(q, l, j)
    quickSort(q, j + 1, r)
}
4、归并排序 O(nlogn)
算法思想:

利用递归将整个区间分为足够小的区间,保证小区间中的数是有序的,然后再逐渐回溯,使大区间也变得有序。最终达到整个区间有序的一个状态。

核心代码:
Go 复制代码
func mergeSort(a []int, l, r int) {
    if l >= r {
        return
    }
​
    mid := (l + r) >> 1
    mergeSort(a, l, mid)
    mergeSort(a, mid+1, r)
    i, j, k := l, mid+1, 0
    for i <= mid && j <= r {
        if a[i] <= a[j] {
            t[k] = a[i]
            k++
            i++
        } else {
            t[k] = a[j]
            k++
            j++
        }
    }
​
    for i <= mid {
        t[k] = a[i]
        k++
        i++
    }
    for j <= r {
        t[k] = a[j]
        k++
        j++
    }
    for i, j := l, 0; i <= r; i++ {
        a[i] = t[j]
        j++
    }
}
5、堆排序
算法思想

堆:即一棵完全二叉树,且每一个点小于等于其左右儿子节点【小根堆】。

建堆:从总数的 n/2 开始往上建,因为必须保证其有左右儿子节点。建堆的过程,就是把父节点、左右儿子节点中较小的元素放到父节点的位置,逐步将大的节点往下移的操作。

核心代码
Go 复制代码
package main
​
​
import "fmt"
​
var n, m, cnt int
var h []int
​
func down (u int) {
    t := u
    if u * 2 <= cnt && h[u * 2] < h[t] {
        t = u * 2
    }
    if u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t] {
        t = u * 2 + 1
    }
    if t != u {
        h[t], h[u] = h[u], h[t]
        down(t)
    }
}
​
func main() {
    fmt.Scan(&n, &m)
    h = make([]int, n + 1)
    
    for i := 1; i <= n; i ++ {
        fmt.Scan(&h[i])
    }
    cnt = n
    
    for i := n / 2; i > 0; i -- {
        down(i)
    }
    for n > 0 {
        n --
        fmt.Printf("%d ", h[1])
        h[1] = h[cnt]
        cnt --
        down(1)
    }
}

未完待续。。。。

相关推荐
马剑威(威哥爱编程)1 小时前
除了递归算法,要如何优化实现文件搜索功能
java·开发语言·算法·递归算法·威哥爱编程·memoization
算法萌新——12 小时前
洛谷P2240——贪心算法
算法·贪心算法
湖北二师的咸鱼2 小时前
专题:二叉树递归遍历
算法·深度优先
宇宙李2 小时前
2024java面试-软实力篇
面试·职场和发展
重生之我要进大厂2 小时前
LeetCode 876
java·开发语言·数据结构·算法·leetcode
Happy鱿鱼3 小时前
C语言-数据结构 有向图拓扑排序TopologicalSort(邻接表存储)
c语言·开发语言·数据结构
KBDYD10103 小时前
C语言--结构体变量和数组的定义、初始化、赋值
c语言·开发语言·数据结构·算法
Crossoads3 小时前
【数据结构】排序算法---桶排序
c语言·开发语言·数据结构·算法·排序算法
自身就是太阳3 小时前
2024蓝桥杯省B好题分析
算法·职场和发展·蓝桥杯
孙小二写代码4 小时前
[leetcode刷题]面试经典150题之1合并两个有序数组(简单)
算法·leetcode·面试