C语言经典实例:21-30例:插入排序、希尔排序1、快速排序、希尔排序2、递归法、完数、斐波那契数列、公约数和公倍数、判断水仙花数统计单词个数
前言
学生C语言最好的方式是练习C语言的经典实例,小编带领大家,通过本文的“C语言经典实例:21-30例“的手把手教会你使用VS2019创建C语言项目、一步一步编写C语的过程,最后达到我们学习C语言各种知识点的目的:C语言基础、C语言for、while循环的运用、希尔排序、快速排序、插入排序的运用等。
1、程序的编写工具
本C语言的实例:21-30例程序,使用Visual Studio 2019软件进行编写。
2、项目的创建
1、在==“C语言经典实例:1-10例”==中创建的“C语言经典实例”的空白解决方案中新建一个名为“C语言经典实例21-30”的C语言项目。
2、将C语言经典实例21-30项目设置为启动项目
如下所示
2、新建一个Main.h头文件和Main.c源文件。
工程项目和文件如下所示。
3、C语言经典实例21-30编写的过程
3.1、C语言经典实例21-插入排序
在Main.h头文件中声明一个func21函数和Insert_Sort函数,然后再Main.c源文件中定义func21函数和Insert_Sort函数,并实现相关的功能。
Main.h头文件中的代码如下
#pragma once
//包含相应的系统头文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define RMAX MAX+1
int R[MAX + 1];
int i;
// 实例21:插入排序
void func21();
void Insert_Sort(int n);
Main.c源文件中的代码如下
#include "Main.h"
int main()
{
system("color 3E");
// 实例21:插入排序
func21();
system("pause");
return 0;
}
// 实例21:插入排序
void func21()
{
srand((unsigned)time(NULL)); // 随机数播种函数
for (i = 1; i < RMAX; i++) // 产生十个随机数
R[i] = rand() % 100 + 1; // 设定随机数范围并输出
printf("产生十个不同的随机数是:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
Insert_Sort(MAX);
puts("\n插入排序后的序列是:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
printf("\n");
}
void Insert_Sort(int n)
{
// 对数组R中的记录R[1..n]按递增序进行插入排序
int i, j;
// 依次插入R[2],…,R[n]
for (i = 2; i <= n; i++)
{
if (R[i] < R[i - 1])
{
// 若R[i]大于等于有序区中所有的R,则R[i]应在原有位置上
R[0] = R[i];
j = i - 1; // R[0]是哨兵,且是R[i]的副本
do // 从右向左在有序区R[1..i-1]中查找R[i]的插入位置
{
R[j + 1] = R[j]; // 将关键字大于R[i]的记录后移
j--;
} while (R[0] < R[j]); // 当R[i]≥R[j]时终止
R[j + 1] = R[0]; // R[i]插入到正确的位置上
}
}
}
调试结果如下
3.2、C语言经典实例22-希尔排序1
在Main.h头文件中声明一个func22函数和primeJudge函数,然后再Main.c源文件中定义func22函数和rimeJudge函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例22:希尔排序1
void func22();
void Bubble_Sort(int n);
Main.c源文件添加的代码如下

// 实例22:希尔排序
void func22()
{
srand((unsigned)time(NULL)); // 随机数播种函数
for (i = 1; i < RMAX; i++) // 产生十个随机数
R[i] = rand() % 100 + 1; // 设定随机数范围并输出
printf("产生十个不同的随机数是:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
Bubble_Sort(MAX);
printf("\n希尔排序后的序列为:");
for (i = 1; i <= 1; i++)
printf("%4d", R[i]);
}
void Bubble_Sort(int n)
{
// R(l..n)是待排序的文件,采用自下向上扫描,对R做冒泡排序
int i, j;
int exchange; // 交换标志
// 最多做n-1趟排序
for (i = 1; i < n; i++)
{
// 本趟排序开始前,交换标志应为假
exchange = 0;
for (j = n - 1; j >= i; j--) // 对当前无序区R[i..n]自下向上扫描
{
// 交换记录
if (R[j + 1] < R[j])
{
// R[0]不是哨兵,仅做暂存单元
R[0] = R[j + 1];
R[j + 1] = R[j];
R[j] = R[0];
// 发生了交换,故将交换标志置为真
exchange = 1;
}
}
if (!exchange) // 本趟排序未发生交换,提前终止算法
return;
}
}
然后在main()函数中只调用func22()函数,其调试结果如下
3.3、C语言经典实例23-快速排序
在Main.h头文件中声明一个func23函数、Quick_Sort函数和Partition函数,然后再Main.c源文件中定义func23函数、Quick_Sort函数和Partition函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例23:快速排序
void func23();
void Quick_Sort(int low, int high);
int Partition(int i, int j);
Main.c源文件添加的代码如下
// 实例23:快速排序
void func23()
{
srand((unsigned)time(NULL)); // 随机数播种函数
for (i = 1; i < RMAX; i++) // 产生十个随机数
R[i] = rand() % 100 + 1; // 设定随机数范围并输出
printf("产生十个不同的随机数是:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
Quick_Sort(1, MAX);
printf("\n快速排序后的序列为:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
printf("\n");
}
void Quick_Sort(int low, int high)
{
// 对R[low..high]快速排序
// 划分后的基准记录的位置
int pivotpos;
// 仅当区间长度大于1时才须排序
if (low < high)
{
// 对R[low..high]做划分
pivotpos = Partition(low, high);
// 对左区间递归排序
Quick_Sort(low, pivotpos - 1);
// 对右区间递归排序
Quick_Sort(pivotpos + 1, high);
}
}
int Partition(int i, int j)
{
// 调用Partition(R,low,high)时,对R[low..high]做划分,
// 并返回基准记录的位置
int pivot = R[i]; // 用区间的第1个记录作为基准
// 从区间两端交替向中间扫描,直至i=j为止
while (i < j)
{
// pivot相当于在位置i上
while (i < j && R[j] >= pivot)
j--; // 从右向左扫描,查找第1个关键字小于pivot.key的记录R[j]
if (i < j) // 表示找到的R[j]的关键字<pivot.key
R[i++] = R[j]; // 相当于交换R[i]和R[j],交换后i指针加1
while (i < j && R[i] <= pivot) // pivot相当于在位置j上
i++; // 从左向右扫描,查找第1个关键字大于pivot.key的记录R[i]
if (i < j) // 表示找到了R[i],使R[i].key>pivot.key
R[j--] = R[i]; // 相当于交换R[i]和R[j],交换后j指针减1
}
R[i] = pivot; // 基准记录已被最后定位
return i;
}
然后在main()函数中只调用func23()函数,其调试结果如下
3.4、C语言经典实例24-希尔排序2
在Main.h头文件中声明一个func24函数、Shell_Sort函数和ShellPass函数,然后再Main.c源文件中定义func24函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例24:希尔排序2
void func24();
void Shell_Sort(int n);
void ShellPass(int d, int n);
Main.c源文件添加的代码如下
// 实例24:希尔排序
void func24()
{
srand((unsigned)time(NULL)); // 随机数播种函数
for (i = 1; i < RMAX; i++) // 产生十个随机数
R[i] = rand() % 100 + 1; // 设定随机数范围并输出
printf("产生十个不同的随机数是:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
Shell_Sort(MAX);
printf("\n希尔排序后的序列为:");
for (i = 1; i < RMAX; i++)
printf("%4d", R[i]);
printf("\n");
}
void Shell_Sort(int n)
{
// 增量初值,不妨设n>0
int increment = n;
do
{
//求下一增量
increment = increment / 3 + 1;
// 一趟增量为increment的Shell插入排序
ShellPass(increment, n);
} while (increment > 1);
}
void ShellPass(int d, int n)
{
// 希尔排序中的一趟排序,d为当前增量
int i, j;
// 将R[d+1..n]分别插入各组当前的有序区
for (i = d + 1; i <= n; i++)
{
if (R[i] < R[i - d])
{
R[0] = R[i];
j = i - d; // R[0]只是暂存单元,不是哨兵
do // 查找R[i]的插入位置
{
R[j + d] = R[j];// 后移记录
j = j - d; // 查找前一记录
} while (j > 0 && R[0] < R[j]);
R[j + d] = R[0]; // 插入R[i]到正确的位置上
}
}
}
然后在main()函数中只调用func24()函数,其调试结果如下
3.5、C语言经典实例25-递归法
在Main.h头文件中声明一个func25函数和reverse函数,然后再Main.c源文件中定义func25函数和reverse函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例25:递归法
void func25();
void reverse(int x);
Main.c源文件添加的代码如下
// 实例25:递归法
void func25()
{
int x;
printf("输入一个整数(不大于五位数):");
scanf("%d", &x); // 由用户输入一个不大于五位数的整数
printf("%d反序输出的结果为:", x);
reverse(x); // 调用reverse()函数
printf("\n");
}
void reverse(int x) // 利用递归法求反序的输出
{
printf("%d", x % 10); // 先输出最后一位数
if (x / 10) // 如果x是大于两位的整数
reverse(x / 10); // 调用它本身
}
然后在main()函数中只调用func25()函数,其调试结果如下
3.6、C语言经典实例26-完数
在Main.h头文件中声明一个func26函数,然后再Main.c源文件中定义func26函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例26:完数
void func26();
Main.c源文件添加的代码如下
// 实例26:完数
void func26()
{
int i, j, k;
for (i = 1; i < 1000; i++)
{
int sum = 0;
for (j = 1; j < i; j++)
{
if (i % j == 0)
{
sum += j;
}
}
if (sum == i)
{
printf("%d its factors are ", i);
for (k = 1; k < i; k++)
{
if (i % k == 0)
{
printf("%d ", k);
}
}
printf("\n");
}
}
}
然后在main()函数中只调用func26()函数,其调试结果如下
3.7、C语言经典实例27-斐波那契数列
在Main.h头文件中声明一个func27函数,然后再Main.c源文件中定义func27函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例27:斐波那契数列
void func27();
Main.c源文件添加的代码如下
// 实例27:斐波那契数列
void func27()
{
long f1, f2, i;
f1 = f2 = 1;
//前两项为1
printf("斐波那契(Fibonacci)数列的前20项有:\n");
//输出f1,f2
printf("%6d%6d", f1, f2);
//计算第3项到第20项
for (i = 3; i <= 20; i += 2)
{
//计算第3项到第20项
for (i = 3; i <= 20; i += 2)
{
//计算下两项
f1 = f1 + f2;
f2 = f1 + f2;
//每输出十项换行
if (i % 11 == 0)
printf("\n");
//输出f1,f2
printf("%6d%6d", f1, f2);
}
}
printf("\n");
}
然后在main()函数中只调用func27()函数,其调试结果如下
3.8、C语言经典实例28-公约数和公倍数
在Main.h头文件中声明一个func28函数,然后再Main.c源文件中定义func28函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例28:公约数和公倍数
void func28();
Main.c源文件添加的代码如下
// 实例28:公约数和公倍数
void func28()
{
int x, y, z, m, n;
printf("请输入两个数:");
scanf("%d%d", &x, &y);
m = x, n = y;
while (y != 0)
{
z = x % y;
x = y;
y = z;
}
printf("最大公约数是: %d\n", x);
printf("最小公倍数是: %d\n", m * n / x);
}
然后在main()函数中只调用func18()函数,其调试结果如下
3.9、C语言经典实例29-统计单词个数
在Main.h头文件中声明一个func29函数,然后再Main.c源文件中定义func29函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例29:统计单词个数
void func29();
Main.c源文件添加的代码如下
// 实例29:统计单词个数
void func29()
{
char s[200];
int i, n = 0, flag = 1;
gets(s);//输入字符串。
for (i = 0; s[i]; i++) //遍历
{
if (flag == 1)
{
if (s[i] != ' ') //单词起始
{
n++;
flag = 0;
}
}
else if (s[i] == ' ') //上一个单词结束。
flag = 1;
}
//输出结果。
printf("%d\n", n);
}
然后在main()函数中只调用func29()函数,其调试结果如下
3.10、C语言经典实例30-判断水仙花数
在Main.h头文件中声明一个func30函数,然后再Main.c源文件中定义func30函数,并实现相关的功能。
Main.h头文件添加的代码如下
// 实例30:判断水仙花数
void func30();
Main.c源文件添加的代码如下
// 实例30:判断水仙花数
void func30()
{
int x, y, z;
int n, m;
while (1)
{
printf("输入一个数字,进行水仙花数的判断: ");
scanf("%d", &n);
x = n / 100; //X 是百位的数
y = (n - x * 100) / 10; //y是十位的数
z = n % 10; //z是个位的数
m = x * x * x + y * y * y + z * z * z;
if (n == m)
printf("%d是水仙花数。\n", n);
else
printf("%d不是是水仙花数。\n", n);
}
}
然后在main()函数中只调用func30()函数,其调试结果如下