NO.1 简单冒泡排序
对比下标从0开始与从1开始的区别。
NO.2 二分法解方程
对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。
假设要求方程f(x)=0的解,给定精确度ξ。其算法是:
- 确定区间[a,b],验证f(a)·f(b)<0
- 求区间(a,b)的中点c
- 判断
(1) 若f(a)·f(c)<0,则令b=c;
(2) 若f(c)·f(b)<0,则令a=c. - 判断f(c)是否达到精确度ξ:即若┃f(c)┃<ξ,则x=c就是使f(x)接近零点的近似值,否则重复2-4.
请按照上面的算法,编程序求解方程f(x)=2x^3-5x^2+3x-6=0,要求精确到0.00001.
#include <stdio.h>
#include<math.h>
double f(double x);
int main( )
{
double a0,a,b0,b,c; //定义区间[a0,b0],中点c
do
{
printf("输入求根区间:");
scanf("%lf %lf",&a0,&b0);
}
while(f(a0)*f(b0)>=0); //保证函数值在[a0,b0]上异号
a=a0;
b=b0;
c=(a+b)/2;
while(fabs(f(c))>1e-5)
{
if(f(c)*f(a)<0)
b=c; //f(a),f(c)异号,把c给b
else
a=c;
c=(a+b)/2;
}
printf("区间[%.2lf,%.2lf]根为:%.5lf",a0,b0,c);
return 0;
}
double f(double x)
{
double fx;
fx=2*x*x*x-5*x*x+3*x-6;
return fx;
}
执行结果
NO.3 有序数组中插入数据
定义好一个有10个元素的数组,先输入9个呈升序的数作为前9个元素,再输入一个数,要求按原来排序的规律将它插入数组中。
例如,9个呈升序的数为1 7 8 17 23 24 59 62 101,需要插入的数字为50,输出的序列则为1 7 8 17 23 24 50 59 62 101。
#include <stdio.h>
#define SIZE 5
int main( )
{
int i,t,j,n,a[SIZE]= {0};
printf("Input SIZE-1 num: ");
for(i=0; i<SIZE-1; i++) //对 SIZE-1 个数输入并排序
scanf("%d",&a[i]);
for(i=0; i<SIZE-2; i++)
for(j=0; j<SIZE-2-i; j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
printf("有序序列:\n");
for(i=0;i<SIZE-1;i++)
printf("%d ",a[i]);
printf("\nInput n : ");
scanf("%d",&n);
//输入数n在序列范围内则插入到a[i+1]位置
/**<
//方案一
if(n<a[0]) //输入数n小于序列最小数则放a[0]
{
for(j=SIZE-1; j>0; j--)
a[j]=a[j-1];
a[0]=n;
for(i=0; i<SIZE; i++)
printf("%d ",a[i]);
return 0;
}
else if(n>a[SIZE-2]) //输入数n大于序列最大数则放a[SIZE-1]
{
a[SIZE-1]=n;
for(i=0; i<SIZE; i++)
printf("%d ",a[i]);
return 0;
}
for(i=0; i<SIZE-1; i++)
{
if(n>=a[i]&&n<=a[i+1])
{
for(j=SIZE-1; j>i; j--)
a[j]=a[j-1];
a[i+1]=n;
for(i=0; i<SIZE; i++)
printf("%d ",a[i]);
break;
}
}
*/
//方案二
for(i=SIZE-2;i>=0&&a[i]>n;i--) //后入,把大的往后挪一个位置
a[i+1]=a[i];
a[i+1]=n; //注意循环结束时i多减了一次
for(i=0;i<SIZE;i++)
printf("%d ",a[i]);
return 0;
}
执行结果
小结
特殊情况是需要考虑,但不能一开始就从特殊情况开始写(比如方案一直接就开始从范围两边开始写),思路应是先着手写普遍(方案二),写好后再酌情是否添加特殊情况。
要注意先整体后局部的思维,不要从小处着眼顺着去推导全局!
NO.4 工资的排序
从文件salary.txt中读入工人的工资(不超过500人),全部增加20%(好事),然后对工资数据进行排序,将排序后的结果保存到文件ordered_salary.txt中。
#include <stdio.h>
#include<stdlib.h>
int main( )
{
int n=0;
double sala[500]= {0};
FILE *fp,*fp1;
if((fp=fopen("salary.txt","r"))==NULL)
{
printf("Can not open!\n");
exit(1);
}
if((fp1=fopen("ordered_salary.txt","w"))==NULL)
{
printf("Can not open!\n");
exit(1);
}
n=0;
while((fscanf(fp,"%lf",&sala[n]))!=EOF) //读取数据放到sala[]
{
sala[n]=sala[n]*1.2;
n++;
} //循环完毕sala[n]==EOF(调试看到为零1.79e-307),说明只读取到n个数(sala[0]开始)
fclose(fp);
int i,j;
double t;
for(i=0; i<n-1; i++)
for(j=0; j<n-i-1; j++)
{
if(sala[j]>sala[j+1])
{
t=sala[j];
sala[j]=sala[j+1];
sala[j+1]=t;
}
}
for(i=0;i<n;i++) //n个数据写入ordered_salary.txt
fprintf(fp1,"%.2lf\n",sala[i]);
fclose(fp1);
return 0;
}
执行结果
小结
易错点:
- 文件指针错定义为int型
- 直接在原文件操作排序。用一个二元素数组a[2]直接循序渐进读取文件数据并排序,只遍历一次,而没有采取把数据写入到500元素数组,对数组元素冒泡排序
- 对文件操作不熟悉