文章目录
C语言常用算法归纳
在C语言的学习过程中,理解和掌握常用算法是非常重要的。这些算法不仅有助于我们解决实际问题,而且能够提高编程的效率和质量。以下是对C语言中常用算法的归纳和总结。
一、基本算法
1. 交换
交换算法是基础中的基础,通常借助一个临时变量来实现两个变量值的交换。
示例代码:
main() {
int a, b, t;
scanf("%d%d", &a, &b);
printf("%d,%d\n", a, b);
t = a; a = b; b = t;
printf("%d,%d\n", a, b);
}
2. 累加
累加算法通过循环实现求和,通常需要一个累加器变量。
示例代码:
main() {
int i, s;
s = 0;
for (i = 1; i <= 100; i++) {
s = s + i; // 累加式
}
printf("1+2+3+...+100=%d\n", s);
}
3. 累乘
累乘算法与累加类似,区别在于它是通过乘法实现累乘。
示例代码:
main() {
int i;
long c;
c = 1;
for (i = 1; i <= 10; i++) {
c = c * i; // 累乘式
}
printf("1*2*3*...*10=%ld\n", c);
}
二、非数值计算常用经典算法
1. 穷举
穷举法通过遍历所有可能的情况来寻找答案。
示例代码:
main() {
int x, g, s, b;
for (x = 100; x <= 999; x++) {
g = x % 10;
s = x / 10 % 10;
b = x / 100;
if (b * b * b + s * s * s + g * g * g == x) {
printf("%d\n", x);
}
}
}
2. 排序
排序算法用于将一系列数据按照特定顺序排列。
(1)冒泡排序
冒泡排序通过反复交换相邻元素实现排序。
示例代码:
main() {
int a[10], i, j, t;
for (i = 0; i < 10; i++) {
scanf("%d", &a[i]);
}
for (j = 1; j <= 9; j++) {
for (i = 0; i < 9 - j; i++) {
if (a[i] > a[i + 1]) {
t = a[i];
a[i] = a[i + 1];
a[i + 1] = t;
}
}
}
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
}
(2)选择排序
选择排序通过选择最小(或最大)元素并将其放置在序列的起始位置。
示例代码:
main() {
int a[10], i, j, k, t;
for (i = 0; i < 10; i++) {
scanf("%d", &a[i]);
}
for (i = 0; i < 9; i++) {
k = i;
for (j = i + 1; j < 10; j++) {
if (a[j] < a[k]) {
k = j;
}
}
if (k != i) {
t = a[i];
a[i] = a[k];
a[k] = t;
}
}
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
}
三、数值计算常用经典算法
1. 级数计算
级数计算通常涉及数列的求和。
示例代码:
main() {
float s;
int i;
s = 0.0;
for (i = 1; i <= 100; i++) {
s = s + 1.0 / i;
}
printf("1+1/2+1/3+...+1/100=%f\n", s);
}
2. 一元非线性方程求根
一元非线性方程求根算法包括牛顿迭代法和二分法。
(1)牛顿迭代法
牛顿迭代法通过迭代逼近方程的根。
示例代码:
#include "math.h"
main() {
float x, x0, f, f1;
x = 1.5;
do {
x0 = x;
f = 2 * x0 * x0 * x0 - 4 * x0 * x0 + 3 * x0 - 6;
f1 = 6 * x0 * x0 - 8 * x0 + 3;
x = x0 - f / f1;
} while (fabs(x - x0) >= 1e-5);
printf("%f\n", x);
}
(2)二分法
二分法通过不断缩小区间来寻找方程的根。
示例代码:
#include "math.h"
main() {
float x1, x2, x0, fx1, fx2, fx0;
do {
printf("Enter x1&x2");
scanf("%f%f", &x1, &x2);
fx1 = 2 * x1 * x1 * x1 - 4 * x1 * x1 + 3 * x1 - 6;
fx2 = 2 * x2 * x2 * x2 - 4 * x2 * x2 + 3 * x2 - 6;
} while (fx1 * fx2 > 0);
do {
x0 = (x1 + x2) / 2;
fx0 = 2 * x0 * x0 * x0 - 4 * x0 * x0 + 3 * x0 - 6;
if ((fx0 * fx1) < 0) {
x2 = x0;
fx2 = fx0;
} else {
x1 = x0;
fx1 = fx0;
}
} while (fabs(fx0) > 1e-5);
printf("%f\n", x0);
}
四、其他常见算法
1. 迭代法
迭代法通过重复计算来逼近问题的解。
示例代码:
main() {
int day, peach;
peach = 1;
for (day = 9; day >= 1; day--) {
peach = (peach + 1) * 2;
}
printf("The first day:%d\n", peach);
}
2. 进制转换
进制转换算法用于将数字从一种进制转换为另一种进制。
示例代码:
void tran(int m, int r, char str[], int *n) {
char sb[] = "0123456789ABCDEF";
int i = 0, g;
do {
g = m % r;
str[i] = sb[g];
m = m / r;
i++;
} while (m != 0);
*n = i;
}
main() {
int x, r0;
int i, n;
char a[50];
scanf("%d%d", &x, &r0);
tran(x, r0, a, &n);
for (i = n - 1; i >= 0; i--) {
printf("%c", a[i]);
}
printf("\n");
}
3. 矩阵转置
矩阵转置算法用于将矩阵的行和列互换。
示例代码:
main() {
int a[2][3], b[3][2], i, j, k = 1;
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
a[i][j] = k++;
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++)
{
b[j][i] = a[i][j];
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("%3d", b[i][j]);
}
printf("\n");
}
}
{
b[j][i] = a[i][j];
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("%3d", b[i][j]);
}
printf("\n");
}
}
3. 矩阵转置
字符处理算法包括字符统计、加密等。
示例代码:
#include "stdio.h"
main() {
char a[100];
int n[26] = {0};
int i;
gets(a);
for (i = 0; a[i] != '\0'; i++) {
n[a[i] - 'a']++;
}
for (i = 0; i < 26; i++) {
if (n[i] != 0) {
printf("%c :%d\n", i + 'a', n[i]);
}
}
}
5. 整数各数位上数字的获取
获取整数各数位上的数字通常通过取余和整除操作实现。
示例代码:
main() {
long x;
int w, q, b, s, g;
scanf("%ld", &x);
if (x < 0) {
printf("-,");
x = -x;
}
w = x / 10000;
q = x / 1000 % 10;
b = x / 100 % 10;
s = x / 10 % 10;
g = x % 10;
printf("%d,%d,%d,%d,%d\n", w, q, b, s, g);
}
6. 辗转相除法求最大公约数
辗转相除法通过连续相除来求两个数的最大公约数。
示例代码:
main() {
int a, b, r;
do {
scanf("%d%d", &a, &b);
} while (a <= 0 || b <= 0);
r = a % b;
while (r != 0) {
a = b;
b = r;
r = a % b;
}
printf("%d\n", b);
}
7. 求最值
求最值算法用于在一组数据中找到最大值或最小值。
示例代码:
main() {
int a[10], i, max, min;
for (i = 0; i < 10; i++) {
scanf("%d", &a[i]);
}
max = min = a[0];
for (i = 1; i < 10; i++) {
if (a[i] > max) {
max = a[i];
} else if (a[i] < min) {
min = a[i];
}
}
printf("max=%d,min=%d\n", max, min);
}
8. 判断素数
判断素数算法用于确定一个数是否为素数。
示例代码:
main() {
int x, k;
do {
scanf("%d", &x);
} while (x <= 1);
for (k = 2; k <= x - 1; k++) {
if (x % k == 0) {
break;
}
}
if (k == x) {
printf("%d is sushu\n", x);
} else {
printf("%d is not sushu\n", x);
}
}
9. 数组元素的插入与删除
数组元素的插入与删除算法用于在数组中添加或移除元素。
示例代码(插入):
main() {
int a[10] = {-1, 3, 6, 9, 13, 22, 27, 32, 49}, x, j, k;
scanf("%d", &x);
if (x > a[8]) {
a[9] = x;
} else {
j = 0;
while (j <= 8 && x > a[j]) {
j++;
}
for (k = 8; k >= j; k--) {
a[k + 1] = a[k];
}
a[j] = x;
}
for (j = 0; j <= 9; j++) {
printf("%d ", a[j]);
}
}
示例代码(删除):
main() {
int fs[10] = {69, 90, 85, 56, 44, 80}, x;
int i, j, n;
n = 10;
scanf("%d", &x);
for (i = 0; i < n; i++) {
if (fs[i] == x) {
break;
}
}
if (i == n) {
printf("Not found!\n");
} else {
for (j = i + 1; j < n; j++) {
fs[j - 1] = fs[j];
}
n = n - 1;
}
for (i = 0; i < n; i++) {
printf("%d ", fs[i]);
}
}
10. 二维数组的其他典型问题
(1)方阵的特点
方阵是行数和列数相等的矩阵,具有一些独特的性质。
示例代码:
main() {
int a[5][5], i, j;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (i == j) {
a[i][j] = 1;
} else if (i < j) {
a[i][j] = 2;
} else {
a[i][j] = 3;
}
}
}
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
printf("%3d", a[i][j]);
}
printf("\n");
}
}
(2)杨辉三角形
杨辉三角形是一种特殊的三角形数列。
示例代码:
main() {
int a[10][10], i, j;
for (i = 0; i < 10; i++) {
a[i][0] = a[i][i] = 1;
for (j = 1; j < i; j++) {
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
}
}
for (i = 0; i < 10; i++) {
for (j = 0; j <= i; j++) {
printf("%4d", a[i][j]);
}
printf("\n");
}
}