嵌入式学习 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),不稳定

今日感悟:

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

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

相关推荐
Logic1015 小时前
C语言/数据结构字符串题解:按字符类型重排(数字→字母→符号)——三趟扫描稳定分区
c语言·数据结构·字符串·时间复杂度·计数排序·算法题·ascii
GEO从入门到精通12 小时前
课程怎么选?2026年GEO学习资源全梳理
学习
夜听莺儿鸣12 小时前
502-002_Linux驱动开发模块化编程
linux·驱动开发·模块化编程
Logic10112 小时前
C语言/数据结构位运算题解:异或XOR找出学习计划中的“独特学习时间“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
wuminyu12 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
优化Henry12 小时前
LTE 载波频率与频点配置详解
运维·网络·学习·5g·信息与通信
小蒋学算法12 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
xiaomu0012313 小时前
高湿环境床垫湿度管理技术框架:湿度阈值、排湿结构与材料选型
经验分享·学习·学习方法
科力锐品牌君13 小时前
应用级灾备 | 海量非结构化数据如何实现高效数据保护
linux·运维·网络·安全·系统安全·数据安全·灾备
zhangrelay13 小时前
ROS项目设计案例智能大模型正经乱答案例
linux·笔记·学习·ubuntu·机器人