C语言程序设计经典100例(全)_第1页
C语言程序设计经典100例(全)_第2页
C语言程序设计经典100例(全)_第3页
C语言程序设计经典100例(全)_第4页
C语言程序设计经典100例(全)_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言程序设计经典100例(全)说明:本文档整理C语言经典100例,按「基础语法→字符串与数组→排序与搜索→数据结构→递归→指针→文件I/O→位操作→实用算法→综合拓展」分为10个模块,每个模块10例。所有代码均遵循C99标准,兼容GCC、VC++等主流编译器,注释详细,可直接复制编译运行,适合初学者入门练习、进阶者巩固提升,兼顾应试与实战需求。第一模块:基础语法(例01~10)例01:HelloWorld(最简单C程序)题目:编写程序,输出“Hello,World!”,熟悉C语言基本结构。分析:C语言程序的基本框架为「包含头文件→主函数→函数体」,printf函数用于格式化输出,分号作为语句结束标志。c

#include<stdio.h>//包含标准输入输出头文件,printf函数需此头文件

intmain(void){//主函数,程序入口,void表示无参数

printf("Hello,World!\n");//输出字符串,\n表示换行

return0;//主函数返回0,表示程序正常结束

}例02:交换两个整数(不借助第三变量,利用异或)题目:输入两个整数,不使用临时变量,通过异或运算实现两数交换并输出。分析:异或运算特性:a^a=0,a^0=a,a^b^a=b。利用此特性,可通过三次异或实现两数交换,避免临时变量占用内存。c

#include<stdio.h>

intmain(void){

inta,b;

printf("请输入两个整数(用空格分隔):");

scanf("%d%d",&a,&b);//输入两个整数,&表示取变量地址

printf("交换前:a=%d,b=%d\n",a,b);

//异或交换核心代码

a=a^b;//a存储a和b的异或结果

b=a^b;//b=(a^b)^b=a,此时b的值变为原来的a

a=a^b;//a=(a^b)^a=b,此时a的值变为原来的b

printf("交换后:a=%d,b=%d\n",a,b);

return0;

}例03:阶乘(递归实现)题目:输入一个正整数n,使用递归函数计算n的阶乘(n!=n×(n-1)×...×1,规定0!=1)。分析:递归的核心是“自身调用自身”,需定义递归终止条件(n=0或n=1时,阶乘为1),否则会陷入无限递归。c

#include<stdio.h>

//递归函数:计算n的阶乘

intfactorial(intn){

if(n==0||n==1){//递归终止条件

return1;

}

returnn*factorial(n-1);//递归调用,n!=n×(n-1)!

}

intmain(void){

intn;

printf("请输入一个正整数:");

scanf("%d",&n);

if(n<0){

printf("输入错误!请输入正整数。\n");

return1;//返回非0,表示程序异常结束

}

printf("%d的阶乘=%d\n",n,factorial(n));

return0;

}例04:斐波那契数列(迭代实现)题目:输出斐波那契数列的前n项(斐波那契数列:1,1,2,3,5,8...,从第3项起,每一项等于前两项之和)。分析:迭代实现相比递归,效率更高(避免重复计算),通过定义三个变量,循环更新前两项的值,依次计算每一项。c

#include<stdio.h>

intmain(void){

intn,a=1,b=1,c;//a为第1项,b为第2项,c存储后续项

printf("请输入要输出的斐波那契数列项数:");

scanf("%d",&n);

if(n<1){

printf("输入错误!请输入正整数。\n");

return1;

}

printf("斐波那契数列前%d项:",n);

for(inti=1;i<=n;i++){

if(i==1||i==2){

printf("%d",1);//前两项均为1

}else{

c=a+b;//第i项=第i-2项+第i-1项

printf("%d",c);

a=b;//更新a为前一项(原b)

b=c;//更新b为当前项(原c)

}

}

printf("\n");

return0;

}例05:判断质数题目:输入一个正整数,判断该数是否为质数(质数:大于1的自然数,除了1和自身外,不能被其他自然数整除)。分析:优化判断逻辑,只需判断到该数的平方根即可(若n能被大于平方根的数整除,則其对应的除数一定小于平方根,无需重复判断)。c

#include<stdio.h>

#include<math.h>//包含sqrt函数(求平方根)的头文件

intmain(void){

intn,flag=1;//flag=1表示默认是质数,flag=0表示非质数

printf("请输入一个正整数:");

scanf("%d",&n);

if(n<=1){//1及以下的数不是质数

flag=0;

}elseif(n==2){//2是唯一的偶质数

flag=1;

}elseif(n%2==0){//偶数(除2外)不是质数

flag=0;

}else{

//遍历从3到sqrt(n)的奇数,判断是否能整除n

for(inti=3;i<=sqrt(n);i+=2){

if(n%i==0){

flag=0;

break;//找到一个除数,直接退出循环

}

}

}

if(flag==1){

printf("%d是质数\n",n);

}else{

printf("%d不是质数\n",n);

}

return0;

}例06:输出指定范围内的所有质数题目:输入两个正整数m和n(m<n),输出m到n之间的所有质数。分析:复用例05的质数判断逻辑,通过循环遍历m到n的所有数,逐个判断是否为质数,若是则输出。c

#include<stdio.h>

#include<math.h>

//自定义函数:判断一个数是否为质数,是则返回1,否则返回0

intisPrime(intnum){

if(num<=1)return0;

if(num==2)return1;

if(num%2==0)return0;

for(inti=3;i<=sqrt(num);i+=2){

if(num%i==0)return0;

}

return1;

}

intmain(void){

intm,n;

printf("请输入两个正整数m和n(m<n):");

scanf("%d%d",&m,&n);

if(m>=n||m<1){

printf("输入错误!请确保m<n且均为正整数。\n");

return1;

}

printf("%d到%d之间的质数:",m,n);

for(inti=m;i<=n;i++){

if(isPrime(i)){

printf("%d",i);

}

}

printf("\n");

return0;

}例07:最大公约数与最小公倍数题目:输入两个正整数,计算并输出它们的最大公约数(GCD)和最小公倍数(LCM)。分析:最大公约数用欧几里得算法(辗转相除法)计算:gcd(a,b)=gcd(b,a%b),直到b=0,此时a即为最大公约数;最小公倍数=两数乘积/最大公约数(避免溢出,优先计算“a/gcd*b”)。c

#include<stdio.h>

//递归实现欧几里得算法,求最大公约数

intgcd(inta,intb){

returnb==0?a:gcd(b,a%b);

}

intmain(void){

inta,b;

printf("请输入两个正整数:");

scanf("%d%d",&a,&b);

intg=gcd(a,b);

intlcm=a/g*b;//先除后乘,避免两数乘积过大导致溢出

printf("最大公约数:%d\n",g);

printf("最小公倍数:%d\n",lcm);

return0;

}例08:反转整数题目:输入一个整数,将其反转后输出(如输入123,输出321;输入-456,输出-654)。分析:通过循环提取整数的每一位(n%10),逐步构建反转后的数(rev=rev*10+余数),同时处理负数(先记录符号,再对绝对值反转)。c

#include<stdio.h>

intmain(void){

intn,rev=0,sign=1;//sign记录符号,默认正数

printf("请输入一个整数:");

scanf("%d",&n);

if(n<0){//若为负数,记录符号并转为正数处理

sign=-1;

n=-n;

}

while(n!=0){

rev=rev*10+n%10;//提取最后一位,加入反转数

n/=10;//去掉最后一位

}

rev*=sign;//恢复符号

printf("反转后的整数为:%d\n",rev);

return0;

}例09:判断回文数题目:输入一个整数,判断该数是否为回文数(回文数:正读和反读相同,如12321、1221,负数一定不是回文数)。分析:复用例08的整数反转逻辑,将原数保存,反转后与原数比较,若相等则为回文数,否则不是。c

#include<stdio.h>

intmain(void){

intn,original,rev=0;

printf("请输入一个整数:");

scanf("%d",&n);

if(n<0){//负数一定不是回文数

printf("不是回文数。\n");

return0;

}

original=n;//保存原数

while(n!=0){

rev=rev*10+n%10;

n/=10;

}

if(original==rev){

printf("是回文数。\n");

}else{

printf("不是回文数。\n");

}

return0;

}例10:判断阿姆斯壮数(三位数)题目:输出所有三位阿姆斯壮数(阿姆斯壮数:一个n位数,其各位数字的n次方和等于该数本身,三位数即各位数字的立方和等于自身,也叫水仙花数)。分析:遍历100~999的所有三位数,拆分出百位、十位、个位,计算三者的立方和,若等于原数则为阿姆斯壮数。c

#include<stdio.h>

#include<math.h>

intmain(void){

printf("三位阿姆斯壮数(水仙花数)有:\n");

for(intn=100;n<=999;n++){

inta=n/100;//百位数字

intb=(n/10)%10;//十位数字

intc=n%10;//个位数字

//计算各位数字的立方和,判断是否等于原数

if(pow(a,3)+pow(b,3)+pow(c,3)==n){

printf("%d",n);

}

}

printf("\n");

return0;

}第二模块:字符串与数组(例11~20)例11:求整数各位数字之和题目:输入一个整数,计算并输出其各位数字之和(如输入123,输出6;输入-456,输出15)。分析:无论正数还是负数,先转为绝对值,再通过循环提取每一位(n%10),累加求和,最后输出总和。c

#include<stdio.h>

intmain(void){

intn,sum=0;

printf("请输入一个整数:");

scanf("%d",&n);

//转为绝对值,避免负数影响求和

if(n<0){

n=-n;

}

while(n!=0){

sum+=n%10;//累加每一位数字

n/=10;//去掉最后一位

}

printf("各位数字之和=%d\n",sum);

return0;

}例12:十进制转二进制(打印二进制表示)题目:输入一个非负整数,使用递归方法打印其二进制表示(如输入10,输出1010)。分析:十进制转二进制的核心是“除2取余,逆序排列”,递归实现可自然实现逆序输出(先递归处理商,再打印余数)。c

#include<stdio.h>

//递归函数:打印非负整数的二进制表示

voidprintBinary(unsignedintn){//用unsignedint避免负数问题

if(n>1){

printBinary(n/2);//递归处理商,先打印高位

}

printf("%d",n%2);//打印余数,即当前位

}

intmain(void){

unsignedintn;

printf("请输入一个非负整数:");

scanf("%u",&n);//%u用于读取unsignedint类型

printf("二进制表示:");

printBinary(n);

printf("\n");

return0;

}例13:二进制字符串转十进制题目:输入一个二进制字符串(仅包含0和1),将其转换为十进制整数并输出(如输入"1010",输出10)。分析:二进制转十进制的规则是“每一位数字×2的对应次方(从右往左,次方从0开始),累加求和”,遍历字符串,逐位计算。c

#include<stdio.h>

#include<string.h>//包含strlen函数(求字符串长度)

intmain(void){

charbinary[20];//存储二进制字符串,最多20位

intdecimal=0;//存储转换后的十进制数

printf("请输入二进制字符串(仅包含0和1):");

scanf("%s",binary);

//遍历字符串,从左到右(高位到低位)

for(inti=0;i<strlen(binary);i++){

//检查字符是否为0或1,非法字符直接报错

if(binary[i]!='0'&&binary[i]!='1'){

printf("输入错误!请输入合法的二进制字符串。\n");

return1;

}

//计算:当前十进制数×2+当前位数字(字符转数字需减'0')

decimal=decimal*2+(binary[i]-'0');

}

printf("二进制字符串%s对应的十进制数为:%d\n",binary,decimal);

return0;

}例14:统计字符串中元音字母的个数题目:输入一行字符,统计其中元音字母(a、e、i、o、u,不区分大小写)的个数。分析:遍历字符串的每一个字符,判断是否为元音字母(包括大小写),若是则计数器加1,最后输出计数器的值。c

#include<stdio.h>

#include<string.h>

#include<ctype.h>//包含tolower函数(转换为小写)

intmain(void){

charstr[100];

intcount=0;

printf("请输入一行字符:");

getchar();//吸收scanf遗留的换行符,避免影响fgets读取

fgets(str,100,stdin);//读取一行字符,包括空格

//遍历字符串,直到遇到结束符'\0'

for(inti=0;str[i]!='\0';i++){

charc=tolower(str[i]);//转换为小写,统一判断

if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'){

count++;

}

}

printf("字符串中元音字母的个数为:%d\n",count);

return0;

}例15:反转字符串题目:输入一个字符串,将其反转后输出(如输入"abcdef",输出"fedcba"),使用双指针法实现。分析:双指针法效率高,定义两个指针(left指向字符串开头,right指向字符串末尾),交换两个指针指向的字符,然后left右移、right左移,直到left>right。c

#include<stdio.h>

#include<string.h>

intmain(void){

charstr[100];

printf("请输入一个字符串:");

scanf("%s",str);

intleft=0;//左指针,指向字符串开头

intright=strlen(str)-1;//右指针,指向字符串末尾

chartemp;//临时变量,用于交换字符

while(left<right){

//交换left和right指向的字符

temp=str[left];

str[left]=str[right];

str[right]=temp;

left++;//左指针右移

right--;//右指针左移

}

printf("反转后的字符串:%s\n",str);

return0;

}例16:判断回文字符串题目:输入一个字符串,判断该字符串是否为回文字符串(回文字符串:正读和反读相同,不区分大小写,忽略空格,如"AbBa"、"AmanaplanacanalPanama")。分析:复用双指针法,先忽略空格、统一大小写,再比较左右指针指向的字符,若所有对应字符都相等,则为回文字符串。c

#include<stdio.h>

#include<string.h>

#include<ctype.h>

intmain(void){

charstr[100];

printf("请输入一个字符串:");

getchar();

fgets(str,100,stdin);

intleft=0;

intright=strlen(str)-1;

intflag=1;//默认为回文字符串

while(left<right){

//跳过左指针指向的空格

while(left<right&&isspace(str[left])){

left++;

}

//跳过右指针指向的空格

while(left<right&&isspace(str[right])){

right--;

}

//统一转为小写,比较字符

if(tolower(str[left])!=tolower(str[right])){

flag=0;

break;

}

left++;

right--;

}

if(flag==1){

printf("是回文字符串。\n");

}else{

printf("不是回文字符串。\n");

}

return0;

}例17:删除字符串中的元音字母题目:输入一个字符串,删除其中所有的元音字母(a、e、i、o、u,不区分大小写),输出处理后的字符串。分析:定义两个指针(i用于遍历原字符串,j用于记录处理后字符串的位置),遍历原字符串,若当前字符不是元音字母,则存入j指向的位置,j自增,最后给处理后的字符串加结束符。c

#include<stdio.h>

#include<string.h>

#include<ctype.h>

intmain(void){

charstr[100],result[100];

printf("请输入一个字符串:");

scanf("%s",str);

intj=0;//记录result数组的下标

for(inti=0;str[i]!='\0';i++){

charc=tolower(str[i]);

//若当前字符不是元音字母,存入result

if(c!='a'&&c!='e'&&c!='i'&&c!='o'&&c!='u'){

result[j++]=str[i];

}

}

result[j]='\0';//给处理后的字符串加结束符

printf("删除元音字母后的字符串:%s\n",result);

return0;

}例18:冒泡排序(整型数组)题目:输入10个整数,使用冒泡排序法对其进行升序排序并输出。分析:冒泡排序的核心是“相邻元素两两比较,若顺序错误则交换”,每一轮排序将最大的元素“冒泡”到数组末尾,共需n-1轮(n为数组长度),可优化为提前判断有序并退出。c

#include<stdio.h>

intmain(void){

intarr[10];

intn=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

//冒泡排序核心逻辑

for(inti=0;i<n-1;i++){//共n-1轮排序

intflag=0;//标记本轮是否发生交换,0表示未交换(已有序)

for(intj=0;j<n-1-i;j++){//每轮少比较i个元素(末尾已排好)

if(arr[j]>arr[j+1]){//相邻元素逆序,交换

inttemp=arr[j];

arr[j]=arr[j+1];

arr[j+1]=temp;

flag=1;//标记发生交换

}

}

if(flag==0){

break;//未发生交换,说明数组已有序,提前退出

}

}

//输出排序后的数组

printf("升序排序后:");

for(inti=0;i<n;i++){

printf("%d",arr[i]);

}

printf("\n");

return0;

}例19:线性查找题目:输入一个整型数组和一个目标值,使用线性查找法找到目标值在数组中的下标(若不存在,输出-1)。分析:线性查找(顺序查找)是最基础的查找方法,遍历数组的每一个元素,与目标值比较,若相等则返回当前下标,遍历结束未找到则返回-1。c

#include<stdio.h>

//线性查找函数:arr为数组,n为数组长度,target为目标值,返回下标(-1表示未找到)

intlinearSearch(intarr[],intn,inttarget){

for(inti=0;i<n;i++){

if(arr[i]==target){

returni;//找到目标值,返回下标

}

}

return-1;//未找到目标值

}

intmain(void){

intarr[10],target,n=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

printf("请输入要查找的目标值:");

scanf("%d",&target);

intindex=linearSearch(arr,n,target);

if(index!=-1){

printf("目标值%d在数组中的下标为:%d\n",target,index);

}else{

printf("目标值%d不在数组中。\n",target);

}

return0;

}例20:递归实现二分查找(要求数组已排序)题目:输入一个已升序排序的整型数组和一个目标值,使用递归方法实现二分查找,找到目标值的下标(若不存在,输出-1)。分析:二分查找的核心是“折半查找”,每次将查找范围缩小一半,需定义递归终止条件(查找范围为空,返回-1;找到目标值,返回下标),仅适用于有序数组。c

#include<stdio.h>

//递归实现二分查找:arr为有序数组,left为左边界,right为右边界,target为目标值

intbinarySearch(intarr[],intleft,intright,inttarget){

if(left>right){

return-1;//递归终止:查找范围为空,未找到

}

intmid=(left+right)/2;//中间下标(避免溢出可写为left+(right-left)/2)

if(arr[mid]==target){

returnmid;//找到目标值,返回下标

}elseif(arr[mid]>target){

//目标值在左半部分,递归查找左区间

returnbinarySearch(arr,left,mid-1,target);

}else{

//目标值在右半部分,递归查找右区间

returnbinarySearch(arr,mid+1,right,target);

}

}

intmain(void){

intarr[10],target,n=10;

printf("请输入10个升序排列的整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

printf("请输入要查找的目标值:");

scanf("%d",&target);

intindex=binarySearch(arr,0,n-1,target);

if(index!=-1){

printf("目标值%d在数组中的下标为:%d\n",target,index);

}else{

printf("目标值%d不在数组中。\n",target);

}

return0;

}第三模块:排序与搜索算法(例21~30)例21:选择排序题目:输入10个整数,使用选择排序法对其进行升序排序并输出。分析:选择排序的核心是“每一轮找到未排序部分的最小值,与未排序部分的第一个元素交换”,共需n-1轮,相比冒泡排序,交换次数更少。c

#include<stdio.h>

intmain(void){

intarr[10],n=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

//选择排序核心逻辑

for(inti=0;i<n-1;i++){//共n-1轮,每轮确定一个最小值的位置

intminIndex=i;//假设未排序部分的第一个元素是最小值

//遍历未排序部分,找到最小值的下标

for(intj=i+1;j<n;j++){

if(arr[j]<arr[minIndex]){

minIndex=j;//更新最小值下标

}

}

//交换最小值与未排序部分的第一个元素

if(minIndex!=i){

inttemp=arr[i];

arr[i]=arr[minIndex];

arr[minIndex]=temp;

}

}

//输出排序后的数组

printf("升序排序后:");

for(inti=0;i<n;i++){

printf("%d",arr[i]);

}

printf("\n");

return0;

}例22:插入排序题目:输入10个整数,使用插入排序法对其进行升序排序并输出。分析:插入排序的核心是“将未排序部分的第一个元素,插入到已排序部分的合适位置”,类比整理扑克牌的过程,适合小规模数据排序。c

#include<stdio.h>

intmain(void){

intarr[10],n=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

//插入排序核心逻辑

for(inti=1;i<n;i++){//从第2个元素开始(下标1),作为待插入元素

inttemp=arr[i];//保存待插入元素

intj=i-1;//j指向已排序部分的最后一个元素

//找到待插入元素的合适位置(已排序部分元素大于待插入元素时,向后移动)

while(j>=0&&arr[j]>temp){

arr[j+1]=arr[j];//元素向后移动

j--;

}

arr[j+1]=temp;//插入待插入元素

}

//输出排序后的数组

printf("升序排序后:");

for(inti=0;i<n;i++){

printf("%d",arr[i]);

}

printf("\n");

return0;

}例23:快速排序(递归实现)题目:输入10个整数,使用递归方法实现快速排序,对其进行升序排序并输出。分析:快速排序的核心是“分治思想”,选择一个基准元素,将数组分为两部分(小于基准的元素在左,大于基准的元素在右),再分别对两部分递归排序,效率高于冒泡、选择、插入排序。c

#include<stdio.h>

//交换两个整数的值

voidswap(int*a,int*b){

inttemp=*a;

*a=*b;

*b=temp;

}

//分区函数:返回基准元素的最终下标,将数组分为两部分

intpartition(intarr[],intleft,intright){

intpivot=arr[right];//选择最右边的元素作为基准

inti=left-1;//i指向小于基准的区域的最后一个元素

for(intj=left;j<right;j++){

//若当前元素小于基准,加入小于基准的区域

if(arr[j]<pivot){

i++;

swap(&arr[i],&arr[j]);

}

}

//将基准元素放到其最终位置(i+1)

swap(&arr[i+1],&arr[right]);

returni+1;//返回基准下标

}

//快速排序递归函数

voidquickSort(intarr[],intleft,intright){

if(left<right){

intpivotIndex=partition(arr,left,right);//分区,得到基准下标

quickSort(arr,left,pivotIndex-1);//递归排序左半部分

quickSort(arr,pivotIndex+1,right);//递归排序右半部分

}

}

intmain(void){

intarr[10],n=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

quickSort(arr,0,n-1);//调用快速排序函数

//输出排序后的数组

printf("升序排序后:");

for(inti=0;i<n;i++){

printf("%d",arr[i]);

}

printf("\n");

return0;

}例24:归并排序题目:输入10个整数,使用归并排序法对其进行升序排序并输出。分析:归并排序的核心是“分治思想+合并有序数组”,先将数组不断拆分为两半,直到每个子数组只有一个元素(天然有序),再将两个有序子数组合并为一个有序数组,稳定性好。c

#include<stdio.h>

#include<stdlib.h>//包含malloc函数(动态分配内存)

//合并两个有序子数组:arr[left..mid]和arr[mid+1..right]

voidmerge(intarr[],intleft,intmid,intright){

intn1=mid-left+1;//左子数组长度

intn2=right-mid;//右子数组长度

//动态分配两个临时数组,存储左、右子数组

int*L=(int*)malloc(n1*sizeof(int));

int*R=(int*)malloc(n2*sizeof(int));

if(L==NULL||R==NULL){//检查内存分配是否成功

printf("内存分配失败!\n");

exit(1);

}

//将左子数组元素复制到L

for(inti=0;i<n1;i++){

L[i]=arr[left+i];

}

//将右子数组元素复制到R

for(intj=0;j<n2;j++){

R[j]=arr[mid+1+j];

}

//合并两个有序子数组,存入原数组

inti=0,j=0,k=left;

while(i<n1&&j<n2){

if(L[i]<=R[j]){

arr[k++]=L[i++];

}else{

arr[k++]=R[j++];

}

}

//复制左子数组剩余元素

while(i<n1){

arr[k++]=L[i++];

}

//复制右子数组剩余元素

while(j<n2){

arr[k++]=R[j++];

}

//释放临时数组内存

free(L);

free(R);

}

//归并排序递归函数

voidmergeSort(intarr[],intleft,intright){

if(left<right){

intmid=left+(right-left)/2;//中间下标,避免溢出

mergeSort(arr,left,mid);//递归排序左子数组

mergeSort(arr,mid+1,right);//递归排序右子数组

merge(arr,left,mid,right);//合并两个有序子数组

}

}

intmain(void){

intarr[10],n=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

mergeSort(arr,0,n-1);//调用归并排序函数

//输出排序后的数组

printf("升序排序后:");

for(inti=0;i<n;i++){

printf("%d",arr[i]);

}

printf("\n");

return0;

}例25:希尔排序题目:输入10个整数,使用希尔排序法对其进行升序排序并输出。分析:希尔排序是插入排序的优化版,核心是“分组插入排序”,先将数组按一定步长分组,对每组进行插入排序,逐步缩小步长,直到步长为1,此时数组已基本有序,最后进行一次插入排序,效率高于普通插入排序。c

#include<stdio.h>

intmain(void){

intarr[10],n=10;

printf("请输入10个整数(用空格分隔):");

for(inti=0;i<n;i++){

scanf("%d",&arr[i]);

}

//希尔排序核心逻辑:步长逐步缩小(此处采用n/2、n/4...1)

for(intgap=n/2;gap>0;gap/=2){

//对每组进行插入排序

for(inti=gap;i<n;i++){

inttemp=arr[i];//待插入元素

intj;

//找到待插入元素在本组中的合适位置

for(j=i;j>=gap&&arr[j-gap]>temp;j-=gap){

arr[j]=arr[j-gap];//元素向后移动(步长为gap)

}

arr[j]=temp;//插入待插入元素

}

}

//输出排序后的数组

printf("升序排序后:");

for(inti=0;i<n;i++){

printf("%d",arr[i]);

}

printf("\n");

return0;

}例26:堆排序题目:输入10个整数,使用堆排序法对其进行升序排序并输出。分析:堆排序的核心是“利用堆的特性(大顶堆:父节点大于子节点)”,先将数组构建为大顶堆,再将堆顶元素(最大值)与堆尾元素交换,缩小堆的范围,重新调整堆,重复此过程,直到堆为空。c

#include<stdio.h>

//交换两个整数的值

voidswap(int*a,int*b){

inttemp=*a;

*a=*b;

*b=temp;

}

//调整堆:将以root为根的子树调整为大顶堆,n为堆的大小

voidheapify(intarr[],intn,introot){

intlargest=root;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论