【C语言】考研复试上机代码题(基础篇)
文章目录
- 一、输入与输出
- 1、温度转换
- 2、排齐数据
- 3、进制转换
- 二、选择分支结构
- 1、分段函数求值
- 2、成绩评定
- 3、平闰年判定
- 4、二次方程的根
- 5、字符大小写
- 三、循环结构程序
- 1、倒数求和
- 4、判断数根
- 5、打印菱形
- 6、最大公约数
- 7、最小公倍数
- 8、复读机
- 四 、数组
- 1、数组的批量增
- 2、数组的批量删
- 3、左小右大
- 4、数组逆序
- 5、数组循环右移
- 6、最值交换
- 7、数组排序
- 8、谁频次最高
- 9、矩阵运算
- 10、矩阵乘积
- 11、找字符索引
- 12、大小写转换
- 13、字符串比较
- 14、字符串排序
- 15、字符串插入
- 16、字符串输出
- 五、结构体 & 链表
- 1、学生信息
- 2、链表的创建
- 3、链表的插入
- 4、链表的删除
- 5、链表的逆序
一、输入与输出
1、温度转换
代码实现
#include <bits/stdc++.h>
using namespace std;
double func(double f) {
return 5*(f-32)/9;
}
int main() {
double c, f;
cin >> f;
c = func(f);
printf("c=%.2lf\n", c);
return 0;
}
2、排齐数据
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
char c; //字母
int bir, age; //出生年,年龄
float hei; //身高
scanf("%c,%d,%f", &c, &bir, &hei);
age = 2024 - bir; //年龄
printf("love:%-8cage:%-8dheight:%-8.2f\n", c, age, hei/100);
return 0;
}
注意:
-
在 C 语言中,
%-8
通常出现在格式化输出函数(如 printf )的格式字符串中,用于控制输出的对齐方式和宽度。 -
-
表示左对齐。如果没有-
,输出默认是右对齐的。 -
8
表示输出的最小宽度为 8 个字符。
3、进制转换
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
printf("%d %o %x %e", n, n, n, (float)(n));
return 0;
}
注意:
- 表示指数形式时,强制转换为
float
类型,你也可以转为double
类型 - 因为
%e
默认被转换的数据类型为浮点数类型,否则会出错
二、选择分支结构
1、分段函数求值
代码实现
#include <bits/stdc++.h>
using namespace std;
int func(int x) {
int y;
if (x >= 0)
y = -x + 1;
else
y = -x - 1;
return y;
}
int main() {
int x;
cin >> x;
cout << func(x) << endl;
return 0;
}
2、成绩评定
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int x;
cin >> x;
if (x >= 90)
cout << 'A';
else if (x >= 80 && x < 90)
cout << 'B';
else if (x >= 70 && x < 80)
cout << 'C';
else if (x >= 60 && x < 70)
cout << 'D';
else
cout << 'E';
cout << endl;
return 0;
}
3、平闰年判定
代码实现
#include <bits/stdc++.h>
using namespace std;
int isLeapYear(int y) {
if ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
return 1;
return 0;
}
int main() {
int y;
cin >> y;
if (isLeapYear(y))
cout << '0';
else
cout << '1';
return 0;
}
4、二次方程的根
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
double a, b, c, delta;
scanf("%lf %lf %lf", &a, &b, &c);
delta = b * b - 4 * a * c;
if (delta > 0) { //两个不同的实数根;
double x1 = (-b + sqrt(delta)) / 2*a;
double x2 = (-b - sqrt(delta)) / 2*a;
printf("x1=%.3lf x2=%.3lf", x1, x2);
}
else if (delta == 0) {
double x1 = (-b) / (2 * a); //一个实数重根;
printf("x1=%.3lf x2=%.3lf", x1, x1);
}
else { //两个共轭复数根。
printf("x1=%.3lf+%.3lfi x2=%.3lf-%.3lfi",
-b / (2*a), (sqrt(-delta)) / (2*a),
-b / (2*a), (sqrt(-delta)) / (2*a)
);
}
cout << endl;
return 0;
}
注意:
5、字符大小写
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
char ch;
cin >> ch;
if (ch >= 'a' && ch <= 'z')
printf("%c\n", ch -= 32); //小写变大小
else if (ch >= 'A' && ch <= 'Z')
printf("%c\n", ch += 32);
else
cout << '0' << endl;
return 0;
}
注意:
三、循环结构程序
1、倒数求和
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
double sum = 0;
for (int i = 1; i <= n; i++) {
sum += (1.0 / i); //写成1.0系统则会默认为浮点数类型计算,否则会丢失精度
}
printf("%.4lf\n", sum);
return 0;
}
2、判断素数
代码实现
#include <bits/stdc++.h>
using namespace std;
int isPrime(int n) {
if (n == 1) //1不是素数
return 0;
for (int i = 2; i * i <= n; i++)
if (n % i == 0)
return 0; //能被整除, 说明不是素数
return 1;
}
int main() {
int n;
cin >> n;
if (isPrime(n))
cout << "yes";
else
cout << "no";
cout << endl;
return 0;
}
注意:
3、判断完数
代码实现
#include <bits/stdc++.h>
using namespace std;
int func(int n) {
int sum = 0;
for (int i = 1; i < n; i++) {
if (n % i == 0)
sum += i;
}
if (sum == n)
return 1;
return 0;
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++)
if(func(i) == 1)
cout << i << " ";
cout << endl;
return 0;
}
4、判断数根
代码实现
#include <bits/stdc++.h>
using namespace std;
int digitSum(int n) {
int sum, lastBit;
sum = 0;
while (n != 0) {
//得到最后一位数字
lastBit = n % 10;
sum += lastBit;
n /= 10;
}
return sum;
}
int main() {
int n;
cin >> n;
while (n >= 10)
n = digitSum(n);
cout << n;
cout << endl;
return 0;
}
5、打印菱形
代码实现
#include <bits/stdc++.h>
using namespace std;
void func(int n) {
//打印高度为n/2+1的上三角形
for (int i = 1; i <= n/2+1; i++) {
for (int j = i; j <= n/2; j++)
printf(" ");
for (int j = 1; j <= 2*i-1; j++)
printf("*");
cout << endl;
}
//打印高度为n/2的倒三角形
for (int i = 1; i <= n/2; i++) {
for (int j = 1; j <= i; j++)
printf(" ");
for (int j = 1; j <= n-2*i; j++)
printf("*");
cout << endl;
}
}
int main() {
int n;
cin >> n;
func(n);
cout << endl;
return 0;
}
上半部分(正三角形):
- 外层循环
for (int i = 1; i <= n/2+1; i++)
控制行数。 - 第一个内层循环
for (int j = i; j <= n/2; j++)
打印空格,确保星号居中。 - 第二个内层循环
for (int j = 1; j <= 2*i-1; j++)
打印星号,星号数量随行数增加。
下半部分(倒三角形):
- 外层循环
for (int i = 1; i <= n/2; i++)
控制行数。 - 第一个内层循环
for (int j = 1; j <= i; j++)
打印空格,确保星号居中。 - 第二个内层循环
for (int j = 1; j <= n-2*i; j++)
打印星号,星号数量随行数减少。
6、最大公约数
代码实现
#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
int main() {
int a, b;
cin >> a >> b;
cout << gcd(a, b);
cout << endl;
return 0;
}
辗转相除法(欧几里得算法):基于以下原理 gcd(a, b) = gcd(b, a % b)
,直到 b 为 0 时,a 就是最大公约数。
或者直接使用 C++ 标准库函数 __gcd(a, b)
,注意引用头文件 #include <algorithm>
7、最小公倍数
代码实现
// 计算最大公约数(GCD)
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// 计算最小公倍数(LCM)
int lcm(int a, int b) {
return (a / gcd(a, b)) * b;
}
int main() {
int a, b;
cin >> a >> b;
cout << lcm(a, b);
cout << endl;
return 0;
}
最大公约数(GCD):
- 使用辗转相除法(欧几里得算法)计算。
- 公式:
gcd(a, b) = gcd(b, a % b)
,直到 b 为 0。
最小公倍数(LCM):
- 公式:
lcm(a, b) = (a / gcd(a, b)) * b
。 - 先除以最大公约数是为了避免乘法溢出。
避免溢出:
- 在计算最小公倍数时,先进行除法运算
(a / gcd(a, b))
,然后再乘以 b,这样可以减少中间结果的大小,避免整数溢出。
8、复读机
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
char ch;
while ((ch = getchar()) != '#')
putchar(ch);
cout << endl;
return 0;
}
注意:
putchar
用于输出单个字符,getchar
用于输入单个字符。- 它们是基于缓冲区的函数,适合处理简单的字符输入输出任务。
- 在实际编程中,
getchar
和putchar
常用于实现简单的字符处理逻辑,如字符统计、回显输入等。
字符统计代码
#include <stdio.h>
int main() {
int count = 0;
printf("请输入一串字符,按回车结束: ");
// 循环读取字符,直到遇到换行符
while (getchar() != '\n') {
count++; // 统计字符数
}
printf("你输入的字符数是: %d\n", count);
return 0;
}
四 、数组
1、数组的批量增
代码实现
#include <bits/stdc++.h>
using namespace std;
#define maxSize 100
// arr1: 1 2 3
// arr2: 4 5
// index=0
// arr1: 4 5 1 2 3
int Insert(int arr1[], int len1, int arr2[], int len2, int index) {
if (len1 + len2 > maxSize || index > len1 || index < 0)
return len1; //空间不够或者插入位置不合法
//先为arr1向后挪动len2个位置, 一定是从后往前挪动
for (int i = len1 - 1; i >= index; i--)
arr1[i + len2] = arr1[i];
//再把arr2插入到arr1中
for (int i = 0; i < len2; i++)
arr1[index + i] = arr2[i];
len1 += len2;
return len1;
}
int main() {
int len1, len2, index;
int arr1[maxSize], arr2[maxSize];
scanf("%d", &len1);
for (int i = 0; i < len1; i++)
scanf("%d", &arr1[i]);
scanf("%d", &len2);
for (int i = 0; i < len2; i++)
scanf("%d", &arr2[i]);
scanf("%d", &index);
len1 = Insert(arr1, len1, arr2, len2, index);
for (int i = 0; i < len1; i++)
cout << arr1[i] << " ";
cout << endl;
return 0;
}
2、数组的批量删
代码实现
#include <bits/stdc++.h>
using namespace std;
#define maxSize 100
int deleteX(int arr[], int n, int x) {
int j = 0;
for (int i = 0; i < n; i++) {
if (arr[i] != x)
arr[j++] = arr[i];
}
return j;
}
int main() {
int n, arr[maxSize], x;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
scanf("%d", &x);
n = deleteX(arr, n, x);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
return 0;
}
3、左小右大
代码实现
#include <bits/stdc++.h>
using namespace std;
//把下标为index的元素左移step步
void Move(int arr[], int index, int step) {
int tmp = arr[index];
int dest = index - step; //计算放入的位置
//从前往后挪出一个位置来
for (int i = index - 1; i >= dest; i--)
arr[i + 1] = arr[i];
arr[dest] = tmp;
}
void Part(int arr[], int n) {
int x = arr[0]; //以第一个元素为基准
int cnt = 0; //记录大于x的元素个数
int i = 1; //从第二个元素开始
while (i < n) {
if (arr[i] < x) //如果小于就移动
Move(arr, i, cnt+1); //左移cnt+1步
else if (arr[i] > x) //如果大于就记录
cnt++;
else { //如果相等, 既要移动, 也要cnt++
Move(arr, i, cnt+1);
cnt++;
}
i++;
}
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
Part(arr, n);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
4、数组逆序
代码实现
#include <bits/stdc++.h>
using namespace std;
void Reverse(int arr[], int n) {
int i, j;
for (i = 0, j = n-1; i <= j; i++, j--) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
Reverse(arr, n);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
5、数组循环右移
代码实现
#include <bits/stdc++.h>
using namespace std;
void reverse(int arr[], int start, int end) {
while (start < end) {
int tmp = arr[start];
arr[start] = arr[end];
arr[end] = tmp;
start++;
end--;
}
}
void Move(int arr[], int n, int step) {
step = step % n;
reverse(arr, 0, n-1); //先整体反转
reverse(arr, 0, step-1); //再反转前0~step-1个元素
reverse(arr, step, n-1); //最后反转step~n-1个元素
}
int main() {
int n, step;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
scanf("%d", &step);
Move(arr, n, step);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
6、最值交换
代码实现
#include <bits/stdc++.h>
using namespace std;
void swapMin(int arr[], int n) {
int min = 0;
for (int i = 1; i < n; i++)
if (arr[i] < arr[min])
min = i;
int tmp = arr[0];
arr[0] = arr[min];
arr[min] = tmp;
}
void swapMax(int arr[], int n) {
int max = 0;
for (int i = 1; i < n; i++)
if (arr[i] > arr[max])
max = i;
int tmp = arr[n - 1];
arr[n - 1] = arr[max];
arr[max] = tmp;
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
swapMin(arr, n);
swapMax(arr, n);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
7、数组排序
代码实现
#include <bits/stdc++.h>
using namespace std;
//这里要加引用
void Swap(int &a, int &b) {
int tmp = a;
a = b;
b = tmp;
}
//冒泡排序
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
bool flag = false;
//从后往前冒泡
for (int j = n - 1; j > i; --j) {
if (arr[j-1] > arr[j])
Swap(arr[j-1], arr[j]);
flag = true;
}
if (!flag)
return;
}
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
bubbleSort(arr, n);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
8、谁频次最高
代码实现
#include <bits/stdc++.h>
using namespace std;
//用来统计第i个元素出现了多少次
int counter(int arr[], int n, int x) {
int cnt = 0;
for (int i = 0; i < n; i++) {
if (arr[i] == x)
cnt++;
}
return cnt;
}
void func(int arr[], int n) {
int maxCount = -1;
int maxCountId = -1;
for (int i = 0; i < n; i++) {
int tmp = counter(arr, n, arr[i]); //统计第i个元素出现了多少次
if (tmp > maxCount) { //如果更大则更新
maxCount = tmp;
maxCountId = i;
}
}
printf("%d %d", arr[maxCountId], maxCount);
}
int main() {
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
func(arr, n);
cout << endl;
return 0;
}
9、矩阵运算
代码实现
以 4x4
的矩阵为例:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
最后一行的索引是 n-1
(即第 4 行,索引为 3):13 14 15 16
最后一列的索引是 n-1
(即第 4 列,索引为 3):4 8 12 16
副对角线是从矩阵的右上角到左下角的连线。对于 n×n
的矩阵,副对角线上的元素满足条件 i + j = n - 1
(其中 i
是行索引,j
是列索引)。
i = 0, j = 3
,为 4i = 1, j = 2
,为 7i = 2, j = 1
,为 10i = 3, j = 0
,为 11
我们需要排除:
- 最后一行:
13 14 15 16
- 最后一列:
4 8 12 16
- 副对角线:
4 7 10 13
排除这些元素后,剩下的元素是:
1 2 3
5 6
9 11
它们的和为:
1 + 2 + 3 + 5 + 6 + 9 + 11 = 37
代码逻辑:
- 排除最后一行:
i < n - 1
- 排除最后一列:
j < n - 1
- 排除副对角线:
i + j != n - 1
10、矩阵乘积
代码实现
#include <bits/stdc++.h>
using namespace std;
void func(int A[10][10], int B[10][10], int m, int n, int p) {
// 定义结果矩阵 C
int C[10][10] = { 0 }; // 初始化为 0
// 计算矩阵乘法
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
for (int k = 0; k < n; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
// 输出结果矩阵 C
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
cout << C[i][j] << " ";
}
cout << endl;
}
}
int main() {
int m, n, p;
// 输入矩阵 A 的维度
cin >> m >> n;
// 定义矩阵 A
int A[10][10];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> A[i][j];
}
}
// 输入矩阵 B 的维度
cin >> n >> p;
// 定义矩阵 B
int B[10][10];
for (int i = 0; i < n; i++) {
for (int j = 0; j < p; j++) {
cin >> B[i][j];
}
}
func(A, B, m, n, p);
return 0;
}
矩阵乘法:
- 矩阵乘法的规则是:结果矩阵 C 的第
(i, j)
个元素是矩阵 A 的第i
行与矩阵 B 的第j
列的点积。
使用三重循环实现矩阵乘法:
- 外层循环遍历结果矩阵 C 的行
i
。 - 中层循环遍历结果矩阵 C 的列
j
。 - 内层循环计算点积
k
。
注意事项:
- 矩阵 A 的列数必须等于矩阵 B 的行数,否则无法进行矩阵乘法。
- 代码假设矩阵的最大维度为
10x10
,可以根据实际需求调整数组大小。 - 输入时需要确保矩阵的维度满足
m < 10, n < 10, p < 10
。
11、找字符索引
代码实现
#include <bits/stdc++.h>
using namespace std;
// 查找字符 ch 在字符串 str 中最后一次出现的位置(从 0 开始计数)
int func(string str, char ch) {
for (int i = str.size() - 1; i >= 0; i--) { // 从后向前遍历
if (str[i] == ch)
return i; // 返回位置(从 0 开始计数)
}
return -1; // 未找到返回 -1
}
int main() {
char ch;
string str;
cin >> ch >> str;
// 查找字符 ch 在字符串 str 中的位置
int index = func(str, ch);
// 输出结果
if (index != -1)
cout << "index=" << index << endl;
else
cout << "Not Found" << endl;
return 0;
}
12、大小写转换
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
char str[101] = { '\0' };
int i = 0;
// 读取输入并处理大小写转换
while (scanf("%c", &str[i]) && (str[i] != '#')) {
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] += 32;
else if (str[i] >= 'a' && str[i] <= 'z')
str[i] -= 32;
i++;
}
// 逆序输出
i--;
while (i >= 0) {
cout << str[i];
i--;
}
return 0;
}
13、字符串比较
代码实现
#include <bits/stdc++.h>
using namespace std;
// 比较两个字符串
int cmpstr(char s1[], char s2[]) {
int i = 0;
// 逐个字符比较
while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0') {
i++;
}
// 根据字符大小返回结果
if (s1[i] == '\0' && s2[i] == '\0') {
return 0; // 字符串相等
} else {
return (s1[i] > s2[i]) ? 1 : -1; // s1 大于 s2 返回 1,否则返回 -1
}
}
int main() {
char s1[101] = { '\0' };
char s2[101] = { '\0' };
cin.getline(s1, 100);
cin.getline(s2, 100);
int ret = cmpstr(s1, s2);
cout << ret << endl;
return 0;
}
使用 cin.getline
替代 gets
:
gets
函数不检查输入长度,容易导致缓冲区溢出。cin.getline
可以指定最大读取长度,避免缓冲区溢出。
14、字符串排序
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n; // 输入字符串的数量
vector<string> str(n); // 创建一个存储字符串的向量
// 输入n个字符串
for (int i = 0; i < n; i++) {
cin >> str[i];
}
// 对字符串进行升序排序
sort(str.begin(), str.end());
// 输出排序后的结果
for (auto s : str) {
cout << s << endl;
}
return 0;
}
vector<string> str(n)
的意思是:
- 创建一个名为
str
的动态数组。 - 这个数组可以存储 n 个
string
类型的元素。 - 数组的初始大小为 n,每个元素是一个空字符串。
15、字符串插入
代码实现
#include <bits/stdc++.h>
using namespace std;
void insertStr(char str1[], char str2[], int pos) {
// // 计算str1和str2的长度
int len1 = strlen(str1);
int len2 = strlen(str2);
// 将pos从1转换为0(C++数组下标从0开始)
pos--;
// 将str1中从pos开始的字符向后移动len2个位置,为插入str2腾出空间
for (int i = len1 - 1; i >= pos; i--)
str1[i + len2] = str1[i];
// 将str2的内容复制到str1的pos位置
for (int i = 0; i < len2; i++)
str1[pos + i] = str2[i];
// 在str1的末尾添加字符串结束符'\0'
str1[len1 + len2] = '\0';
}
int main() {
char str1[101] = { '\0' };
char str2[101] = { '\0' };
int pos;
cin.getline(str1, 100);
cin.getline(str2, 100);
cin >> pos;
insertStr(str1, str2, pos);
printf("%s", str1);
cout << endl;
return 0;
}
16、字符串输出
代码实现
#include <bits/stdc++.h>
using namespace std;
void deleteStr(char str[], char subStr[]) {
// 计算str和subStr长度
int len = strlen(str);
int subLen = strlen(subStr);
int start = 0; // 初始化起始查找位置
// 当起始位置不超过【str长度减去subStr长度】时, 进入循环
while (start <= len - subLen) {
int flag = 1; // 标志位,用于判断是否找到匹配的子字符串
// 遍历子字符串的每个字符
for (int i = 0; i < subLen; i++) {
if (str[start + i] != subStr[i]) { // 如果字符不匹配
flag = 0; // 设置标志位为0,表示未找到匹配
break; // 跳出循环
}
}
// 如果找到匹配的子字符串
if (flag) {
// 将str中从start + subLen开始的字符向前移动subLen个位置,覆盖子字符串
for (int i = start + subLen; i < len; i++) {
str[i - subLen] = str[i];
}
// 更新str的长度
len = len - subLen;
}
else {
start++; // 未找到匹配,起始位置向后移动一位
}
}
str[len] = '\0';
}
int main() {
char str[101] = { '\0' };
char subStr[101] = { '\0' };
cin.getline(str, 100);
cin.getline(subStr, 100);
deleteStr(str, subStr);
printf("%s", str);
cout << endl;
return 0;
}
五、结构体 & 链表
1、学生信息
代码实现
#include <bits/stdc++.h>
using namespace std;
//需要额外的一个字符来存储字符串结束符 '\0'
typedef struct Student {
char name[11];
char gender[11];
int age;
char id[11];
}Stu;
int main() {
int n;
cin >> n;
Stu s[n];
for (int i = 0; i < n; i++) {
cin >> s[i].name >> s[i].gender >> s[i].age >> s[i].id;
// 检查是否有重复的ID
for (int j = 0; j < i; j++) {
if (0 == strcmp(s[i].id, s[j].id))
{
cout << "ERROR" << endl;
i--; // 重新录入, i要回退
break;
}
}
}
// 按照格式打印输出
for (int i = 0; i < n; i++) {
printf("%-10s%-10s%-10d%-10s\n", s[i].name, s[i].gender, s[i].age, s[i].id);
}
return 0;
}
2、链表的创建
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
}LNode, *LinkList;
// 创建带头结点的单链表(尾插法)
LinkList createList(int arr[], int n) {
LinkList head = (LinkList)malloc(sizeof(LNode)); // 创建头节点
head->next = NULL; // 初始化头节点的 next 指针为空
LNode *rear = head; // rear 指向链表的最后一个节点
for (int i = 0; i < n; i++) {
LNode* newNode = (LNode*)malloc(sizeof(LNode)); // 创建新节点
newNode->data = arr[i]; // 设置新节点的数据
newNode->next = NULL; // 初始化新节点的 next 指针为空
rear->next = newNode; // 将新节点连接到链表的末尾
rear = newNode; // 更新 rear 指针
}
return head; // 返回链表的头节点
}
// 打印单链表
void displayList(LinkList head) {
LNode* cur = head->next;
while (cur != NULL) {
printf("%d->", cur->data);
cur = cur->next;
}
cout << "NULL";
}
int main() {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
LinkList head = createList(arr, n);
displayList(head);
return 0;
}
LNode
:
- 是
struct node
的别名。 - 用于表示链表中的一个节点。
- 例如:
LNode newNode;
声明一个节点变量。
*LinkList
:
- 是
struct node*
的别名。 - 用于表示指向链表节点的指针,通常用来表示整个链表(指向头结点)。
- 例如:
LinkList head;
声明一个指向链表头节点的指针。
LNode
的功能:
- 表示链表中的一个节点。
- 包含两个成员:
data
:存储节点的数据。next
:指向下一个节点的指针。
*LinkList
的功能:
- 表示指向链表节点的指针。
- 通常用于指向链表的头节点,从而表示整个链表。
- 例如:
LinkList head;
表示指向链表头节点的指针。head->next
可以访问链表中的第一个节点。
总结:
LNode
是链表节点的别名,用于表示链表中的一个节点。*LinkList
是指向链表节点的指针的别名,通常用于表示整个链表(指向头节点)。- 在
createList
函数中,LNode
用于创建新节点,*LinkList
用于返回链表的头节点。
3、链表的插入
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
}LNode, *LinkList;
// 创建带头结点的单链表(尾插法)
LinkList createList(int arr[], int n) {
LinkList head = (LinkList)malloc(sizeof(LNode)); // 创建头节点
head->next = NULL; // 初始化头节点的 next 指针为空
LNode *rear = head; // rear 指向链表的最后一个节点
for (int i = 0; i < n; i++) {
LNode* newNode = (LNode*)malloc(sizeof(LNode)); // 创建新节点
newNode->data = arr[i]; // 设置新节点的数据
newNode->next = NULL; // 初始化新节点的 next 指针为空
rear->next = newNode; // 将新节点连接到链表的末尾
rear = newNode; // 更新 rear 指针
}
return head; // 返回链表的头节点
}
// 在第pos个位置插入x
int insertList(LinkList head, int x, int pos) {
if (pos < 0)
return 0;
// 生成要插入的结点
LNode* newNode = (LNode*)malloc(sizeof(LNode));
newNode->data = x;
newNode->next = NULL;
// 找到待插入的位置
LNode* pre = head;
for (int i = 0; i < pos; i++) {
if (pre->next != NULL)
pre = pre->next;
else
return 0;
}
//开始插入
newNode->next = pre->next;
pre->next = newNode;
return 1;
}
// 打印单链表
void displayList(LinkList head) {
LNode* cur = head->next;
while (cur != NULL) {
printf("%d->", cur->data);
cur = cur->next;
}
cout << "NULL";
}
int main() {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
// 尾插法创建单链表
LinkList head = createList(arr, n);
// 在第pos个尾插插入x
int x, pos;
cin >> x >> pos;
insertList(head, x, pos);
// 打印链表
displayList(head);
return 0;
}
4、链表的删除
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
}LNode, *LinkList;
// 创建带头结点的单链表(尾插法)
LinkList createList(int arr[], int n) {
LinkList head = (LinkList)malloc(sizeof(LNode)); // 创建头节点
head->next = NULL; // 初始化头节点的 next 指针为空
LNode *rear = head; // rear 指向链表的最后一个节点
for (int i = 0; i < n; i++) {
LNode* newNode = (LNode*)malloc(sizeof(LNode)); // 创建新节点
newNode->data = arr[i]; // 设置新节点的数据
newNode->next = NULL; // 初始化新节点的 next 指针为空
rear->next = newNode; // 将新节点连接到链表的末尾
rear = newNode; // 更新 rear 指针
}
return head; // 返回链表的头节点
}
// 删除第pos个位置的结点
int deleteList(LinkList head, int pos) {
if (pos < 0)
return 0;
// 找到待删除结点的前一个结点
LNode* pre = head;
int step = 0;
while (step < pos) {
if (pre->next != NULL) {
pre = pre->next;
step++;
}
else {
return 0;
}
}
if (pre->next != NULL) {
LNode* delNode = pre->next;
pre->next = delNode->next;
free(delNode);
return 1;
}
return 0;
}
// 打印单链表
void displayList(LinkList head) {
LNode* cur = head->next;
while (cur != NULL) {
printf("%d->", cur->data);
cur = cur->next;
}
cout << "NULL";
}
int main() {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
// 尾插法创建单链表
LinkList head = createList(arr, n);
// 删除第pos个位置的元素
int pos;
cin >> pos;
deleteList(head, pos);
// 打印链表
displayList(head);
return 0;
}
注意:这里是删除索引位置的元素。
5、链表的逆序
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int data;
struct node *next;
}LNode, *LinkList;
// 创建带头结点的单链表(尾插法)
LinkList createList(int arr[], int n) {
LinkList head = (LinkList)malloc(sizeof(LNode)); // 创建头节点
head->next = NULL; // 初始化头节点的 next 指针为空
LNode *rear = head; // rear 指向链表的最后一个节点
for (int i = 0; i < n; i++) {
LNode* newNode = (LNode*)malloc(sizeof(LNode)); // 创建新节点
newNode->data = arr[i]; // 设置新节点的数据
newNode->next = NULL; // 初始化新节点的 next 指针为空
rear->next = newNode; // 将新节点连接到链表的末尾
rear = newNode; // 更新 rear 指针
}
return head; // 返回链表的头节点
}
// 链表逆序
void reverseList(LinkList head) {
LNode *cur = head->next;
head->next = NULL;
while (cur != NULL) {
LNode* curNext = cur->next;
cur->next = head->next;
head->next = cur;
cur = curNext;
}
}
// 打印单链表
void displayList(LinkList head) {
LNode* cur = head->next;
while (cur != NULL) {
printf("%d->", cur->data);
cur = cur->next;
}
cout << "NULL";
}
int main() {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
// 尾插法创建单链表
LinkList head = createList(arr, n);
// 链表逆序
reverseList(head);
// 打印链表
displayList(head);
return 0;
}