嵌入式学习 day25:哈希表及排序与查找

一、哈希表

1.1 什么是哈希表

哈希表是一种根据键(Key) 直接访问数据的数据结构。它通过哈希函数把键映射到一个下标,然后直接在该位置存取数据。

1.2 为什么用哈希表

数据结构 查找元素
数组 O(n)(遍历)
有序数组 O(log n)(二分查找)
链表 O(n)
二叉搜索树 O(log n)
哈希表 O(1)(近乎常数时间)

哈希表的查找速度非常快,和元素数量多少关系不大。

1.3 哈希冲突

不同数据经过哈希函数映射后得到相同的键值,就叫哈希冲突

解决哈希冲突的常用方法

  • 链地址法:每个哈希桶里挂一个链表,冲突的数据放在链表里

  • 开放地址法:如果当前位置被占了,就往后找空位

text

复制代码
链地址法示例:
索引0 → [数据A] → [数据B]  ← A和B冲突了,串成链表
索引1 → [数据C]
索引2 → NULL
索引3 → [数据D] → [数据E] → [数据F]

二、排序算法

2.1 排序算法对比

算法 平均时间复杂度 最坏情况 稳定性 特点
冒泡排序 O(n²) O(n²) 稳定 相邻比较,大数后移
选择排序 O(n²) O(n²) 不稳定 每轮选最小放前面
插入排序 O(n²) O(n²) 稳定 将元素插入有序部分
希尔排序 O(n log n) O(n²) 不稳定 分组+插入排序
快速排序 O(n log n) O(n²) 不稳定 分治,选基准值分组

2.2 冒泡排序

相邻两个元素比较,大的往后移。每轮结束当前最大的数就"沉"到了最后面。

c

复制代码
void BubbleSort(int a[], int len)
{
    for (int i = 0; i < len - 1; i++) {
        for (int j = 0; j < len - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                int tmp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = tmp;
            }
        }
    }
}

2.3 选择排序

每轮从剩下的元素里找到最小的,放到前面。

c

复制代码
void SelectionSort(int a[], int len)
{
    for (int i = 0; i < len - 1; i++) {
        int min = i;
        for (int j = i + 1; j < len; j++) {
            if (a[j] < a[min]) {
                min = j;
            }
        }
        if (min != i) {
            int tmp = a[i];
            a[i] = a[min];
            a[min] = tmp;
        }
    }
}

2.4 插入排序

把数组分成"已排序"和"未排序"两部分,从未排序部分取元素插入到已排序部分的正确位置。

c

复制代码
void InsertionSort(int a[], int len)
{
    for (int i = 1; i < len; i++) {
        int key = a[i];
        int j = i - 1;
        while (j >= 0 && a[j] > key) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = key;
    }
}

2.5 希尔排序

插入排序的改进版。先把数据按步长分组,每组分别做插入排序,步长逐步缩小,最后步长为1时做最后一次插入排序。

c

复制代码
void ShellSort(int a[], int len)
{
    for (int gap = len / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < len; i++) {
            int key = a[i];
            int j = i - gap;
            while (j >= 0 && a[j] > key) {
                a[j + gap] = a[j];
                j -= gap;
            }
            a[j + gap] = key;
        }
    }
}

2.6 快速排序

核心思想是分治。选一个基准值,把比它小的放左边、比它大的放右边,然后递归对左右两边做同样的操作。

c

复制代码
int Partition(int a[], int low, int high)
{
    int key = a[low];
    while (low < high) {
        while (low < high && a[high] >= key) high--;
        a[low] = a[high];
        while (low < high && a[low] <= key) low++;
        a[high] = a[low];
    }
    a[low] = key;
    return low;
}

void QuickSort(int a[], int low, int high)
{
    if (low < high) {
        int mid = Partition(a, low, high);
        QuickSort(a, low, mid - 1);
        QuickSort(a, mid + 1, high);
    }
}

三、今日总结

今天学了哈希表排序算法,核心要点如下:

哈希表

  1. 通过哈希函数把键映射到存储位置

  2. 查找时间复杂度接近 O(1)

  3. 哈希冲突用链地址法或开放地址法解决

排序算法

  1. 冒泡排序:相邻比较,大数后移 → O(n²),稳定

  2. 选择排序:每轮选最小放前面 → O(n²),不稳定

  3. 插入排序:元素插入有序部分 → O(n²),稳定

  4. 希尔排序:分组插入排序 → O(n log n),不稳定

  5. 快速排序:分治,选基准值分组 → O(n log n),不稳定

今日感悟

哈希表用空间换时间,多占点内存,换来接近瞬时的查找速度。

不同场景适用不同的算法,数据量小、要求稳定,用插入排序;数据量大、追求速度,用快速排序。

相关推荐
传奇开心果编程4 小时前
【xilem0.4基础语法学与练】第13课:Xilem 0.4 最简短代码体现“一切皆设计图“
学习·rust·前端框架
小雪崩4 小时前
嵌入式学习 day45:51单片机基础
学习·51单片机
彧azz6 小时前
Java学习语法篇:变量
java·学习
bosins6 小时前
WSL 迁移指南:如何将 Linux 环境完整复制到另一台电脑
linux·运维·服务器
Yanjun2i6 小时前
Agent学习记录五:Pydantic验证
人工智能·python·学习
繁星蓝雨7 小时前
C++的设计与演进大纲(如何从C语言一步步成长为C++)
c语言·开发语言·c++·c++历史·c++演进
程序员阿鹏7 小时前
为什么MySQL InnoDB选择B+树?
数据结构·数据库·b树·sql·mysql·算法·缓存
yutian06067 小时前
C: Unix UTC 时间戳转为 UTC+8 北京时间
c语言·unix
企鹅的蚂蚁8 小时前
LubanCat RK3588 实时 Linux 开发(六):启用 gs_usb 驱动并完成 USB-CAN 收发
linux·rk3588·linux驱动·socketcan·gs_usb·usb-can
2601_962299888 小时前
Linux执行Python脚本方法
linux·python·脚本·解释器·shebang