在计算机科学中,后缀数组(Suffix Array)是一种用于字符串处理的强大数据结构。它广泛应用于文本压缩、生物信息学、全文搜索等领域。本教程将带你从零开始,用C语言一步步实现后缀数组,并解释其原理,即使你是编程小白也能轻松掌握!
假设我们有一个字符串 S = "banana",它的所有后缀包括:
banana(从索引 0 开始)anana(从索引 1 开始)nana(从索引 2 开始)ana(从索引 3 开始)na(从索引 4 开始)a(从索引 5 开始)后缀数组就是将这些后缀按字典序排序后,记录它们起始位置的数组。
对 "banana" 排序后的后缀顺序为:
a → 起始位置 5ana → 起始位置 3anana → 起始位置 1banana → 起始位置 0na → 起始位置 4nana → 起始位置 2因此,后缀数组为:[5, 3, 1, 0, 4, 2]

后缀数组是许多高级字符串算法的基础。相比后缀树,它占用内存更少,且易于用数组实现。常见用途包括:
对于初学者,我们可以先用最直观的方法:生成所有后缀,然后排序。虽然效率不高(时间复杂度 O(n² log n)),但逻辑清晰,便于理解。
以下是完整的 C 语言代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>int compare_suffixes(const void* a, const void* b) { int i = *(const int*)a; int j = *(const int*)b; char* str = (char*)global_str; // 注意:这里为了简化,使用全局变量 return strcmp(str + i, str + j);}char* global_str; // 全局字符串指针,供比较函数使用void build_suffix_array(char* str, int n, int* suffix_arr) { // 初始化后缀数组:0, 1, 2, ..., n-1 for (int i = 0; i < n; i++) { suffix_arr[i] = i; } global_str = str; // 设置全局字符串 // 使用 qsort 对后缀起始位置排序 qsort(suffix_arr, n, sizeof(int), compare_suffixes);}int main() { char str[] = "banana"; int n = strlen(str); int suffix_arr[n]; build_suffix_array(str, n, suffix_arr); printf("后缀数组: "); for (int i = 0; i < n; i++) { printf("%d ", suffix_arr[i]); } printf("\n"); // 打印排序后的后缀(验证) printf("排序后的后缀:\n"); for (int i = 0; i < n; i++) { printf("%s\n", str + suffix_arr[i]); } return 0;}
这段代码使用了 C 标准库的 qsort 函数对后缀起始索引进行排序。注意:由于 qsort 的比较函数不能直接传入额外参数,我们使用了一个全局变量 global_str 来传递字符串地址(实际项目中建议使用更安全的方式,如封装结构体)。
上述暴力方法适用于小字符串,但对于大文本(如 DNA 序列)效率太低。工业级实现通常采用 O(n log n) 的倍增算法(也称 Manber-Myers 算法)。该算法通过逐步比较后缀的 1、2、4、8... 长度前缀来排序,避免了每次比较整个后缀。
虽然实现较复杂,但它是掌握高级C语言后缀数组技术的关键。感兴趣的同学可以在掌握基础后深入学习。
通过本教程,你已经了解了:
后缀数组是算法竞赛和系统开发中的实用工具。掌握它,你就离成为字符串处理高手又近了一步!
记住关键词:后缀数组、C语言后缀数组、字符串算法、后缀排序——它们是你深入学习的路标。
本文由主机测评网于2025-12-06发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025123629.html