这道C语言练习题"题目1114:排列"是典型的编程竞赛和计算机专业基础训练题目。作为从教多年的C语言讲师,我发现排列组合类题目在各大高校的编程作业、ACM竞赛初选和IT企业校招笔试中出现的频率极高。这类题目主要考察以下几个核心能力:
在实际教学场景中,学生最容易在以下环节出错:
对于长度为n的序列,全排列共有n!种可能。常见的实现方案有三种:
考虑到本题的C语言环境限制,我们采用最基础的递归回溯方案。其核心思想是:
c复制void permute(int *arr, int start, int end) {
if (start == end) {
printArray(arr, end+1);
return;
}
for (int i = start; i <= end; i++) {
swap(&arr[start], &arr[i]);
permute(arr, start+1, end);
swap(&arr[start], &arr[i]); // 回溯
}
}
注意:当n>10时,普通递归解法可能栈溢出,需考虑迭代方案
c复制#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
c复制void permute(int arr[], int start, int end) {
// 终止条件:到达最后一个元素
if (start == end) {
printArray(arr, end + 1);
return;
}
for (int i = start; i <= end; i++) {
// 避免重复排列(当有重复元素时)
if (i != start && arr[i] == arr[start])
continue;
swap(&arr[start], &arr[i]);
permute(arr, start + 1, end);
swap(&arr[start], &arr[i]); // 回溯
}
}
c复制int main() {
int n;
printf("输入元素个数: ");
scanf("%d", &n);
int arr[n];
printf("输入%d个整数: ", n);
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
printf("所有排列结果:\n");
permute(arr, 0, n - 1);
return 0;
}
当输入数组包含重复元素时,原始算法会产生重复排列。解决方案:
c复制// 在permute函数内添加判断
if (i > start && arr[i] == arr[start])
continue;
当n较大时(如n>10),可考虑:
经过多年教学验证,学生在掌握排列算法时最容易忽视的三个要点:
建议的练习路线图:
对于算法竞赛选手,还需要特别注意: