从PTA实战到算法内功:三种英文单词排序策略的深度剖析与工程化思考
最近在辅导几位准备程序设计类考试的同学时,我发现“英文单词排序”这道题出现的频率相当高。表面看,它只是要求按单词长度排序,长度相同则保持输入顺序,但仔细琢磨,这道题其实是一个绝佳的算法思维训练场。它不像纯粹的算法题那样抽象,而是将我们熟悉的字符串操作与经典的排序思想结合起来,考察的不仅是代码实现能力,更是对不同场景下技术选型的判断力。很多同学在初次面对时,可能会直接套用课本上的冒泡排序,这当然能解决问题,但在追求效率的竞赛环境或未来的工程实践中,我们能否做得更好?今天,我们就抛开简单的题解思路,深入聊聊解决这个问题的三种核心方法——从最直观的冒泡排序,到更高效的选择排序,再到性能卓越的快速排序,并探讨它们背后的适用哲学与实现细节。无论你是正在备战PTA、蓝桥杯等考试的学生,还是希望夯实C语言与算法基础的开发者,相信这次探讨都能带来一些新的启发。
1. 问题重定义与核心挑战拆解
在动手写任何一行代码之前,我们有必要把题目要求翻译成更精确的“技术规格说明书”。原题要求输入若干英文单词(以#结束),按长度从小到大排序输出,长度相同时维持原始输入顺序。这里隐藏了几个关键约束和挑战:
- 输入的不确定性:单词数量上限为20个,每个单词长度小于10。这意味着我们不需要处理海量数据,但必须设计一个灵活的输入终止机制。
- 排序的关键字:排序的依据是字符串的长度,而非字典序。因此,直接使用
strcmp是不行的,我们需要strlen函数。 - 稳定性的要求:“长度相同则按输入顺序不变”,这在算法中称为稳定性。一个稳定的排序算法能保证相等元素的相对次序在排序后保持不变。这对我们选择算法提出了明确要求。
- 数据交换的复杂性:排序过程中不可避免要交换元素。对于整型数组,交换是简单的赋值操作;但对于字符串(在C中表现为字符数组),交换意味着整个字符序列的拷贝,这需要使用
strcpy函数,并且要小心缓冲区溢出。
为了更清晰地对比后续不同算法的操作对象和逻辑,我们先统一数据的存储方式。在C语言中,一个存储最多20个、每个最长10个字符的单词集合,最自然的表示是一个二维字符数组:
char words[20][11]; // 20行,每行11个字符(10个字母+1个结束符'\0')
输入循环可以这样构建:
int count = 0;
while (count < 20) {
scanf("%s", words[count]);
if (words[count][0] == '#') {
break;
}
count++;
}
变量count同时记录了有效单词的数量,它将作为后续排序循环的边界。接下来,我们将看到三种不同的算法如何在这个数据框架上施展拳脚。
2. 方法一:冒泡排序——直观易懂的起点
冒泡排序大概是大多数人算法之旅的“初恋”。它的思想朴素得像水中的气泡:每一轮遍历,比较相邻的两个元素,如果它们的顺序不对就交换,这样每一轮都会将当前未排序部分的最大(或最小)元素“浮”到正确位置。
2.1 算法原理与适应性改造
对于我们的单词排序问题,标准的数值冒泡排序需要做两点关键改造:
- 比较条件:从比较数值大小改为比较字符串长度,即
strlen(words[j]) > strlen(words[j+1])。 - 交换操作:从交换两个整数改为交换两个字符串,这需要借助一个临时字符数组和三次
strcpy调用。
一个典型的实现片段如下:
char temp[11];
for (int i = 0; i < count - 1; i++) { // 进行 count-1 轮
for (int j = 0; j < count - 1 - i; j++) { // 每轮比较相邻元素
if (strlen(words[j]) > strlen(words[j+1])) {
// 交换 words[j] 和 words[j+1]
strcpy(temp, words[j]);
strcpy(words[j], words[j+1]);
strcpy(words[j+1], temp);
}
}
}
2.2 优势、局限与复杂度分析
冒泡排序最大的优势在于实现简单,逻辑清晰,特别适合教学和小数据量(如本题上限20)的场景。它也是一种稳定的排序算法,天然满足题目中长度相同时保持原序的要求。
然而,它的性能缺陷也很明显。其时间复杂度是 O(n²),这意味着如果数据量翻倍,运行时间大致会变为四倍。在我们的例子中,每次比较长度后若需要交换,都会引发三次字符串拷贝(strcpy),而字符串拷贝本身也是一个

&spm=1001.2101.3001.5002&articleId=150203692&d=1&t=3&u=5fb1a7f869944ba19b8e589ddbd59827)
84

被折叠的 条评论
为什么被折叠?



