C语言编程_牛顿迭代法求方程2
c语言计算机编程三种方法求解非线性方程
本科专业学年论文题目:非线性方程求解比较姓名:何娟专业:计算机科学技术系班级:08级本科(2)班指导老师:刘晓娜完成日期:2010年11 月21 日题 目:非线性方程求解比较摘 要本文给出了三种求解非线性方程的方法,分别是二分法,牛顿迭代法,割弦法。
二分法巧妙地利用插值得到的点以及有根区间中点这两点处的函数值,缩小隔根区间,以期望得到更快的收敛速度。
牛顿迭代法是非线性方程根的一种常见的数值方法,对于非线性方程的单重零点来说,牛顿迭代法一般具有局部二阶收敛性,但是当所求的根X*是F(X)的M 重根时,M 是大于等于2的整数,此时牛顿迭代法只有一阶收敛性。
弦截法是将牛顿迭代公式中用差商F(k x )-F(1-k x )/ (k x - 1-k x )代替导数'()k F x 。
本文给出了算法改进的具体步骤及算法流程图相关的数值结果也说明了方法的有效性。
关 键 词 : 二分法;牛顿迭代法;割弦法;非线性方程目录第一章绪论- 3 -第二章求解非线性方程的三种常见算法……………………………- 4-2.1 二分法………………………………………………………-4 -2.2 牛顿迭代法……………………………………………………- 5 -2.3 割弦法- 6 -第三章求解非线性方程的三种算法比较- 8 -3.1 二分法求解方法- 8 -3.2 牛顿迭代法求解- 10 -3.3 割弦法求解- 11 -参考文献- 14 -第一章绪论在科技飞速发展的今天,计算机已经成为我们生活中不可缺少的一部分了,在我们生活与生产中扮演越来越重要的角色,而科学计算已经成为科学计算的重要方法之一,其应用范围已渗透到所有科学领域,作为科学与工程计算的数学工具,计算方法已成为高等院校数学与应用数学,信息与计算科学,应用物理学等必修课。
在永恒变化发展的自然界与人类社会中,在研究其内部规律的各个科学领域中,更深刻、更精确地描述其内部规律的数学工具之一,就是非线性方程。
c++ 牛顿迭代法解方程组
c++ 牛顿迭代法解方程组牛顿迭代法是一种求解方程的数值方法,它通过迭代逼近的方式,不断接近方程的解。
首先,我们需要定义要解的方程组。
假设我们要求解的方程组为:f1(x1, x2, ..., xn) = 0f2(x1, x2, ..., xn) = 0...fn(x1, x2, ..., xn) = 0其中,f1, f2, ..., fn是方程组中的各个方程,x1, x2, ..., xn是方程组的未知数。
接下来,我们可以利用牛顿迭代法来求解这个方程组。
具体步骤如下:1. 首先,我们需要给出方程组的初始猜测解。
设初始解为x^(0) = (x1^(0), x2^(0), ..., xn^(0))。
2. 然后,我们计算方程组在初始解处的Jacobi矩阵J^(0),即:J^(0) = [[∂f1/∂x1, ∂f1/∂x2, ..., ∂f1/∂xn],[∂f2/∂x1, ∂f2/∂x2, ..., ∂f2/∂xn],...[∂fn/∂x1, ∂fn/∂x2, ..., ∂fn/∂xn]]其中,∂f/∂x表示方程f对未知数x的偏导数。
3. 接下来,我们计算方程组在初始解处的函数值向量F^(0),即:F^(0) = [f1(x1^(0), x2^(0), ..., xn^(0)),f2(x1^(0), x2^(0), ..., xn^(0)),...fn(x1^(0), x2^(0), ..., xn^(0))]4. 然后,我们可以利用牛顿迭代公式来更新解,即:x^(k+1) = x^(k) - (J^(k))^(-1) * F^(k)其中,x^(k)表示第k次迭代的解,J^(k)表示第k次迭代的Jacobi矩阵,F^(k)表示第k次迭代的函数值向量。
5. 将更新后的解x^(k+1)代入方程组,并重新计算Jacobi矩阵和函数值向量。
6. 重复步骤4和步骤5,直到满足迭代停止的条件。
常见的迭代停止条件有:达到最大迭代次数、解的变化小于某个阈值、函数值的范数小于某个阈值等。
c语言实验报告 (2)
C语言实验报告说明1,所有程序均用VC6。
0编译运行,文件名命名为姓名+日期,因为实验存在补做,所以并不是按照日期先后排列的。
2,为了使截图清晰,手动将运行窗口由“黑底白字"改为了“白底黑字”.实验2 数据类型、运算符和表达式一、实验目的:(1)掌握C语言数据类型,熟悉如何定义一个整型、字符型、实型变量、以及对它们赋值的方法。
(2)学会使用C的有关算术运算符,以及包含这些运算符的表达式,特别是自加(++)和自减(――)运算符的使用。
(3)掌握C语言的输入和输出函数的使用(4)进一步熟悉C程序的编辑、编译、连接和运行的过程.三、程序调试与问题解决:(1)输人并运行下面的程序#include<stdio.h>void main(){char c1,c2;c1='a’;c2=’b';printf(”%c %c\n”,c1,c2);}错误!运行此程序.错误!在上面printf语句的下面再增加一个printf语句。
printf(”%d%d\n",c1,c2);再运行,并分析结果。
输出结果如图,编译成功,无错误.错误!将第3行改为int c1,c2;再运行,并分析结果。
错误!再将第4、5行改为c1=a;c2=b;再运行,并分析结果。
a,b没有定义,编译报错。
错误!再将第4、5行改为c1=‘’a‘’;c2=‘’b‘’;再运行,并分析结果。
○6再将第4、5行改为c1=300;c2=400;再运行,并分析结果.以字符型输出时,输出的将是300,400对应的字符.(2)输人并运行教材第3章习题3. 6给出的程序#include〈stdio.h〉main (){char c1=’a’,c2=’b’,c3=’c',c4=’\101’,c5=’\116';printf("a%c b%c\tc%c\tabc\n",c1,c2,c3);printf(”\t\b%c %c\n”,c4,c5);}#include<stdio.h>void main(){int a,b;unsigned c,d;long e,f;a=100;b=-100;e=50000;f=32767;c=a;d=b;printf("%d,%d\n",a,b);printf(”%u,%u\n",a,b);printf("%u,%u\n",c,d);c=a=e; d=b=f;printf(”%d,%d\n",a,b);printf("%u,%u\n”,c,d);}请对照程序和运行结果分析:①将一个负整数斌给一个无符号的变t,会得到什么结果.画出它们在内存中的表示形式。
C++实现 牛顿迭代 解非线性方程组
C++实现牛顿迭代解非线性方程组(二元二次为例)求解{0=x*x-2*x-y+0.5;0=x*x+4*y*y-4;}的方程#include<iostream>#include<cmath>#define N 2 // 非线性方程组中方程个数、未知量个数#define Epsilon 0.0001 // 差向量1范数的上限#define Max 100 // 最大迭代次数using namespace std;const int N2=2*N;int main(){void ff(float xx[N],float yy[N]); //计算向量函数的因变量向量yy[N]void ffjacobian(float xx[N],float yy[N][N]); //计算雅克比矩阵yy[N][N]void inv_jacobian(float yy[N][N],float inv[N][N]); //计算雅克比矩阵的逆矩阵invvoid newdundiedai(float x0[N], float inv[N][N],float y0[N],float x1[N]);//由近似解向量x0 计算近似解向量x1float x0[N]={2.0,0.25},y0[N],jacobian[N][N],invjacobian[N][N],x1[N],errornorm;int i,j,iter=0;//如果取消对x0的初始化,撤销下面两行的注释符,就可以由键盘x读入初始近似解向量for( i=0;i<N;i++)cin>>x0[i];cout<<"初始近似解向量:"<<endl;for (i=0;i<N;i++)cout<<x0[i]<<" ";cout<<endl;cout<<endl;do{iter=iter+1;cout<<"第"<<iter<<" 次迭代开始"<<endl; //计算向量函数的因变量向量y0ff(x0,y0); //计算雅克比矩阵jacobianffjacobian(x0,jacobian); //计算雅克比矩阵的逆矩阵invjacobian inv_jacobian(jacobian,invjacobian); //由近似解向量x0 计算近似解向量x1 newdundiedai(x0, invjacobian,y0,x1); //计算差向量的1范数errornormerrornorm=0;for (i=0;i<N;i++)errornorm=errornorm+fabs(x1[i]-x0[i]);if (errornorm<Epsilon) break;for (i=0;i<N;i++)x0[i]=x1[i];} while (iter<Max);return 0;}void ff(float xx[N],float yy[N]) //调用函数{float x,y;int i;x=xx[0];y=xx[1];yy[0]=x*x-2*x-y+0.5;yy[1]=x*x+4*y*y-4; //计算初值位置的值cout<<"向量函数的因变量向量是:"<<endl;for( i=0;i<N;i++)cout<<yy[i]<<" ";cout<<endl;cout<<endl;}void ffjacobian(float xx[N],float yy[N][N]){float x,y;int i,j;x=xx[0];y=xx[1];//jacobian have n*n element //计算函数雅克比的值yy[0][0]=2*x-2;yy[0][1]=-1;yy[1][0]=2*x;yy[1][1]=8*y;cout<<"雅克比矩阵是:"<<endl;for( i=0;i<N;i++){for(j=0;j<N;j++)cout<<yy[i][j]<<" ";cout<<endl;}cout<<endl;}void inv_jacobian(float yy[N][N],float inv[N][N]) {float aug[N][N2],L;int i,j,k;cout<<"开始计算雅克比矩阵的逆矩阵:"<<endl; for (i=0;i<N;i++){ for(j=0;j<N;j++)aug[i][j]=yy[i][j];for(j=N;j<N2;j++)if(j==i+N) aug[i][j]=1;else aug[i][j]=0;}for (i=0;i<N;i++){ for(j=0;j<N2;j++)cout<<aug[i][j]<<" ";cout<<endl;}cout<<endl;for (i=0;i<N;i++){for (k=i+1;k<N;k++){L=-aug[k][i]/aug[i][i];for(j=i;j<N2;j++)aug[k][j]=aug[k][j]+L*aug[i][j];}}for (i=0;i<N;i++){ for(j=0;j<N2;j++)cout<<aug[i][j]<<" ";cout<<endl;cout<<endl;for (i=N-1;i>0;i--){for (k=i-1;k>=0;k--){L=-aug[k][i]/aug[i][i];for(j=N2-1;j>=0;j--)aug[k][j]=aug[k][j]+L*aug[i][j];}}for (i=0;i<N;i++){ for(j=0;j<N2;j++)cout<<aug[i][j]<<" ";cout<<endl;}cout<<endl;for (i=N-1;i>=0;i--)for(j=N2-1;j>=0;j--)aug[i][j]=aug[i][j]/aug[i][i];for (i=0;i<N;i++){ for(j=0;j<N2;j++)cout<<aug[i][j]<<" ";cout<<endl;for(j=N;j<N2;j++)inv[i][j-N]=aug[i][j];}cout<<endl;cout<<"雅克比矩阵的逆矩阵:"<<endl; for (i=0;i<N;i++){ for(j=0;j<N;j++)cout<<inv[i][j]<<" ";cout<<endl;cout<<endl;}void newdundiedai(float x0[N], float inv[N][N],float y0[N],float x1[N]) {int i,j;float sum=0;for(i=0;i<N;i++){ sum=0;for(j=0;j<N;j++)sum=sum+inv[i][j]*y0[j];x1[i]=x0[i]-sum;}cout<<"近似解向量:"<<endl;for (i=0;i<N;i++)cout<<x1[i]<<" ";cout<<endl;cout<<endl;}。
c语言上机实验题及参考答案
5、两个乒乓球队进行比赛,各出3人,甲队为A,B,C 3人,乙队为X,Y,Z 3人。已抽签决定比赛名单。有人向队员打听比赛的名单。A说他不和X比,C说他不和X、Z比。请编程序找出3队赛手的名单。(C语言源程序文件名为45.c,本程序运行结果:A--Z B--X C--Y)
2 14 14
5 10 15
8 6 16
11 2 17)
2、编写程序:输入两个正整数,求其最大公约数和最小公倍数。(如输入12和8,则最大公约数为4,最小公倍数为24)(C语言源程序文件名为42.c。要求求最大公约数用欧几里得的辗转相除法实现)。
3、编写程序实现以下功能:输入一个正整数,打印出它是否素数。(C语言源程序文件名为43.c)
例如:有定义int a=3;执行输出语句:printf(“a=%3d”,a);则输出结果显示为:a= 3(3左边有两个空格)
n(代表一个正整数)
对实数,表示输出n位小数。
例如:有定义float x=1.2;执行输出语句:printf(“x=%6.2f”,x);则输出结果显示为:x= 1.20(数字左边有两个空格)。
三、附加题:
9、编程实现:从键盘上输入一个三位正整数m,输出将m的个位,十位,百位反序而成的三位数(例如:输入m的值123,则输出m的值为321)(要求:文件名为15.c,提示:可用算术运算符“/”和“%”先分离出m的各个位数,再重新组合成新的数,例如用表达式“123%10”就能求出123的个位数3)。
三、实验题目:
if语句基本形式:if(条件){语句一;}
拟牛顿法c语言
C语言版拟牛顿法算法的设计与实现
一、引言
拟牛顿法是一种广泛应用于优化问题的迭代算法。
它以牛顿法为基础,但避免了牛顿法中需要计算和存储逆矩阵的困难。
在C语言中实现拟牛顿法算法,可以充分利用C语言的性能优势,提高算法的执行效率。
本文将详细介绍拟牛顿法算法的设计与实现过程。
二、算法设计
1.算法概述
拟牛顿法的基本思想是利用当前迭代点的一阶导数信息,构造一个近似于真实Hessian矩阵的拟合矩阵,并用它来更新搜索方向。
每次迭代,算法沿着搜索方向进行一维搜索,找到最优步长,然后更新迭代点。
重复这个过程,直到满足收敛条件。
2.算法步骤
(1) 初始化:选择初始点x0,设置初始矩阵B0,通常取为单位矩阵。
(2) 迭代:对于k=0,1,2,...,执行以下步骤: a. 计算函数f在xk的一阶导数g=f'(xk) b. 计算搜索方向d=-B*g c. 沿着搜索方向d进行一维搜索,找到最优步长α,使得f(xk+αd)最小。
d. 更新迭代点xk+1=xk+αd e. 更新拟合矩阵Bk+1,使其满足拟牛顿条件。
(3) 收敛判断:当满足收敛条件时,算法终止;否则,继续迭代。
三、算法实现
下面是一个简单的拟牛顿法算法实现示例:。
C语言计算开方范文
C语言计算开方范文一、牛顿迭代法牛顿迭代法是一种数值计算方法,用于求解方程的近似解。
对于开方操作,我们可以将其转化为求解方程x^2-a=0的根。
根据牛顿迭代法的思想,我们可以通过不断逼近方程的根来得到开方的结果。
具体步骤如下:1. 初始化一个变量 guess 为 a 的一半,即 guess = a / 2- 计算当前迭代的 guess 值的平方与 a 的差值 diff = guess * guess - a。
-如果差值小于误差范围,则跳出迭代。
- 否则,更新 guess 值为上一次的 guess 值减去 diff 与 2 * guess 的商,即 guess = (guess - diff / (2 * guess))。
3. 返回最终的 guess 值作为开方的结果。
以下是使用C语言实现牛顿迭代法的代码示例:```c#include <stdio.h>double sqrt_newton(double a)double guess = a / 2;double diff = guess * guess - a;int count = 0;guess = guess - diff / (2 * guess);diff = guess * guess - a;count++;}printf("迭代次数:%d\n", count);return guess;int maidouble a = 16;double result = sqrt_newton(a);printf("开方结果: %lf\n", result);return 0;```以上代码中的 a 表示待开方的数,可以根据需要进行修改。
result 表示开方的结果,count 表示迭代的次数。
二、二分法二分法也是一种常用的数值计算方法,适用于在有序列表中查找一些元素的问题。
对于计算开方,我们可以利用二分法在一定的误差范围内逼近开方的结果。
C语言程序设计(第三版)习题库答案
x1=__(x0+a/x0)/2__;
} while(__x1>1e-5__);
printf("%g\n",x1);
}
3x2x
15、用牛顿迭代法求方程2x4360在1.5附近的根。
#include <stdio.h>
#include __<math.h>__
#define f(x) 2*x*x*x-4*x*x+3*x-6
main(){
int x,y,z,t=0;
scanf("%d %d %d",&x,&y,&z);
if(x>y)
{t=y;y=x;x=t;}
if(x>z)
{t=z;z=x;x=t;}
if(y>z)
{t=z;z=y;y=t;}
printf("%d\n",z);
}
6、输入两个正整数m和n,求其最大公约数和最小公倍数。
落地时共经过多少米?第10次反弹多高?
#include <stdio.h>
main(){
int i,n=10;
double h=100,s=100;
for(i=2;i<=n;i++){
h*=__0.5 __;
s%f,h=%f\n",s,h);
}
13、猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一
}
2、输入一个华氏温度,要求输出摄氏温度。公式为c=5(F-32)/9
输出要求有文字说明,取位2小数。
#include <stdio.h>
牛顿迭代法c++代码
牛顿迭代法c++代码牛顿迭代法是一种数值计算方法,用于求解非线性方程的根。
它是通过不断迭代逼近的方式来逐步逼近方程的根。
在数学上,给定一个函数f(x),我们希望找到一个近似的解x*,使得f(x*)=0。
牛顿迭代法的基本思想是利用切线逼近函数曲线,求得切线与x轴的交点,将该交点作为新的近似解,不断迭代直到满足精度要求。
牛顿迭代法的迭代公式为:x_n+1 = x_n - f(x_n)/f'(x_n)。
下面是一个用C++实现牛顿迭代法的示例代码:```cpp#include <iostream>#include <cmath>double f(double x) {return x*x - 2; // 求解方程x^2 - 2 = 0}double f_derivative(double x) {return 2*x; // 方程f(x) = x^2 - 2的导数为2x}double newton_method(double x0, double epsilon, intmax_iterations) {double x = x0;int iteration = 0;while (iteration < max_iterations) {double fx = f(x);double f_derivative_x = f_derivative(x);if (std::abs(fx) < epsilon) {std::cout << "Found solution: x = " << x << std::endl;return x;}if (std::abs(f_derivative_x) < epsilon) {std::cout << "Derivative is close to zero. Exiting." << std::endl;return std::numeric_limits<double>::quiet_NaN(); // 返回NaN表示迭代失败}x = x - fx/f_derivative_x;++iteration;}std::cout << "Maximum iterations reached. Exiting." << std::endl;return std::numeric_limits<double>::quiet_NaN(); // 返回NaN 表示迭代失败}int main() {double x0 = 1.0; // 初始值double epsilon = 1e-6; // 精度要求int max_iterations = 1000; // 最大迭代次数double root = newton_method(x0, epsilon, max_iterations);return 0;}```以上代码中,我们定义了两个函数f(x)和f_derivative(x),分别表示了要求解的非线性方程和该方程的导数。
C语言编程_牛顿迭代法求方程2
牛顿迭代公式设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f'(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f'(x0),称x1为r的一次近似值。
过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标 x2 = x1-f(x1)/f'(x1),称x2为r的二次近似值。
重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式。
解非线性方程f(x)=0的牛顿法是把非线性方程线性化的一种近似方法。
把f(x)在x0点附近展开成泰勒级数 f(x) = f(x0)+(x-x0)f'(x0)+(x-x0)^2*f''(x0)/2! +… 取其线性部分,作为非线性方程f(x) = 0的近似方程,即泰勒展开的前两项,则有f(x0)+f'(x0)(x-x0)-f(x)=0 设f'(x0)≠0则其解为x1=x0-f(x0)/f'(x0) 这样,得到牛顿法的一个迭代序列:x(n+1)=x(n)-f(x(n))/f'(x(n))。
牛顿迭代法又称牛顿切线法,它采用以下方法求根:先任意设定一个与真实的根接近的值x0作为第一个近似根,由x0求出f(x0),过(x0,f(x0))点做f(x)的切线,交x轴于x1,把它作为第二次近似根,再由x1求出f(x1),再过(x1,f(x1))点做f(x)的切线,交x轴于x2,再求出f(x2),再作切线……如此继续下去,直到足够接近真正的x*为止。
就是牛顿迭代公式。
例1 用牛顿迭代法求方程2x3-4x2+3x-6=0在1.5附近的根。
本题中,f(x)= 2x3-4x2+3x-6=((2x-4)x+3)x-6f’(x)= 6x2-8x+3=(6x-8)x+3#include "stdio.h"#include "math.h"voidmain(){ float x1,x0,f,f1;x1=1.5;do{ x0=x1;f=((2*x0-4)*x0+3)*x0-6;f1=(6*x0-8)*x0+3;x1=x0-f/f1;}while(fabs(x1-x0)>=1e-5);printf("THe root of equation is %5.2f\n",x1);}例题2 #include <math.h>main(){float x,x0,d,f,fd;x0=0;do {f=2*x0*x0*x0-4*x0*x0+3*x0-6;fd=6*x0*x0-8*x0+3;d=f/fd;x=x0-d;x0=x;}while(fabs(d)>1e-3);printf("x=%f\n",x); }X+=X-=X*X赋值表达式此表达式为自右向左赋值,如X的初值为12,此表达式赋值步骤如下:1. 先进行“X-=X*X”的运算,它相当于X=X-X*X,X的值为12-144=-1322. 再进行“X+=-132”的运算,相当于X=X+(-132),X的值为-132-132=-264。
c语言编写的计算方法里的迭代法的例子
• 建立一个函数
f ( x) x a 从而导数可知
2
1.设定一个x的初值x0; 2.用以上公式求出x的下一个值x1; 3.再将x1 的值赋给x0,代入公式 又可以重新求 出一个x1,如此反复; 4.如此继续下去,直到前后俩次求出的值绝 对值小于0.00005
自己查找资料编写的一个应用到迭代法的一个小程序建立一个函数从而导数编写的一个应用到迭代法的一 个小程序
• 首先建立一个问题就是求
x a
• 求平方公式的迭代公式为 xn1 1/ 2 ( xn a / xn ) • 要求前后求出的值的绝对值小于0.00005 • 迭代公式的推导,是根据牛顿迭代法推导而出 xk 1 xk
程序如下
• • • • • • • • • • • • • • • • #include<stdio.h> #include<math.h> int main() { float a,x0,x1; printf("enter a positive number:"); scanf("%f",&a); x0=a/2; x1=(x0+a/x0)/2; do {x0=x1; x1=(x0+a/x0)/2; }while (fabs(x0-x1)>=1e-8); printf("The square root of %5.2f is %12.9f\n",a,x1); return 0; }
C语言程序设计谭浩强第三版课后习题答案
第六章循环语句6.1 输入两个正数,求最大公约数和最小公倍数.int main(){int a,b,num1,num2,temp; printf(" 请输入两个正整数:\n");scanf("%d,%d",&num1,&num2); if(num1<num2){temp=num1; num1=num2;num2=temp;} a=num1,b=num2; while(b!=0){ temp=a%b; a=b; b=temp;}printf(" 它们的最大公约数为:%d\n",a);printf(" 它们的最小公倍数为:%d\n",num1*num2/a); return 0;} 我觉得这样不是更简单吗:首先用scanf 输入两个整数a,b if(a <b) c=a;else c=b;for(;c>0;c--)if((a%c)&&(b%c)==0)break;printf("最大公约数为%d",c);printf(" 最大公倍数为%d",a*b/c);6.2输入一行字符,分别统计出其中英文字母,空格,数字和其它字符的个数解:#include <stdio.h>int main(){char c;int letters=0,space=0,degit=0,other=0;printf(" 请输入一行字符:\n");while((c=getchar())!='\n'){ if(c>='a'&&c<='z' || c>'A'&&c<='Z') letters++; else if(c==' ') space++; elseif(c>='0'&&c<='9') digit++; else other++;}printf(" 其中: 字母数=%d 空格数=%d 数字数=%d 其它字符数=%d\n",letters,space, digit,other);return 0;}6.3求s(n)=a+aa+aaa+…+aa••之值,其中a是一个数字,n表示a的位数。
《C语言程序设计基础》习题集(含答案)
第一章C语言概述1.1、选择题(1)一个C语言程序是由()组成。
A. 一个主程序及若干个子程序B. 一个主程序C. 一个主函数及若干个子函数D. 一个主函数(2) 一个C语言程序总是从()开始执行。
A. 主过程B. 主函数C. 子程序D. 主程序(3) main函数在源程序中的位置()。
A. 必须在最开始B. 必须在子函数的后面C. 可以任意D. 必须在最后(4) 一个C程序的执行是从()。
A. 本程序的第一个函数开始,到最后一个函数结束B. 本程序的main函数开始,到最后一个函数结束C. 本程序的main函数开始,通常也在main函数结束D. 本程序的第一个函数开始,到main函数结束(5) 以下叙述不正确的是()。
A. 一个C程序可由一个或多个函数组成B. 一个C程序必须包含一个main函数C. 在C程序中,注释只能位于一条语句的最后面D. C程序的基本组成单位是函数1.2、编程题(1)参照本章例题,编程输出如下信息:**********Very good!**********(2)编写一个C程序,输出以下信息:******Turbo C ** * * * *1.3 请根据自己的认识,写出C语言的主要特点。
1.4 简述C程序主要由哪些部分构成?1.5 用户编写的C程序上机运行要经过哪些步骤?第二章基本数据类型和表达式2.1 单项选择题(1) 以下不能用作变量名的是()A)_26 B)case C)scanf D)Double(2) 以下合法的八进制数是()A)0135 B)068 C)013.45 D)o7(3) 若变量已正确定义,以下非法的表达式是()A)a/=b+c B)a%(4.0) C)a=1/2*(x=y=20,x*3) D)a=b=c (4) 设x 为int 类型,其值为11,则表达式:(x++*1/3)的值是()A)3 B)4 C)11 D)12(5) 若题中各变量已正确定义并赋值,下面符合C 语法的表达式是()A )a%=7.6; B)a++,a=7+b+c C)int(12.3)%4 D)a=c+b=a+7 (6) 设k 和x 均为int 型变量,且k=7,x=12,则能使值为3的表达式是()A)x%=k%=5 B)x%=(k-k%5) C)x%=k-k%5 D)(x%=k)- (k%=5) (7) 能正确表示数学公式|)sin(|x ,的C 语言表达式是()A)sqrt(abs(sin(x*π/180)))B)sqrt(abs(sin(x*3.14/180))) C)sqrt(sin(x))D)sqrt (fabs (sin(x*3.14/180)))(8) 以下变量x 、y 、z 均为double 型且已正确赋值,不能正确表示代数式z y x的C 语言表达式是()A)x/y*z B)x*(1/(y*z)) C)x/y*1/z D)x/y/z (9) 以下叙述中正确的是()A ) A )C 程序中,赋值运算符的优先级最低。
求平方根c语言函数
求平方根c语言函数在数学中,平方根是一个非常基本的概念,它是一个数的正平方根或负平方根。
在计算机科学中,求平方根也是一项非常基本的任务。
C语言作为一种广泛应用于计算机科学和编程领域的编程语言,自然也需要一种求平方根的函数来满足其应用需求。
在C语言中,求平方根的函数可以通过调用math.h库中的sqrt()函数来实现。
sqrt()函数的原型如下:double sqrt(double x);该函数接受一个double类型的参数x,返回x的正平方根。
需要注意的是,如果x是一个负数,则返回NaN(Not a Number)。
下面是一个简单的例子,展示了如何使用sqrt()函数来计算一个数的平方根:#include <stdio.h>#include <math.h>int main() {double x = 25.0;double result = sqrt(x);printf('The square root of %lf is %lf', x, result);return 0;}输出:The square root of 25.000000 is 5.000000在上面的例子中,我们定义了一个double类型的变量x,并将其赋值为25。
然后,我们调用了sqrt()函数来计算x的平方根,并将结果存储在另一个double类型的变量result中。
最后,我们使用printf()函数来输出结果。
除了使用sqrt()函数外,我们也可以手动实现一个求平方根的函数。
其中,最常见的方法是使用牛顿迭代法。
牛顿迭代法是一种用于近似求解方程的迭代方法,它可以用来求解各种类型的方程,包括求平方根。
牛顿迭代法的基本思路是:从一个初始值开始,不断用切线来逼近函数的零点,直到达到所需的精度为止。
对于求平方根,我们可以将其转化为求解方程x^2-a=0,其中a为待求平方根的数。
牛顿迭代法的迭代公式如下:x_{n+1} = x_n - frac{f(x_n)}{f'(x_n)}其中,x_n表示第n次迭代的结果,f(x)表示待求解的方程,f'(x)表示f(x)的导数。
算法-牛顿迭代法求平方根
算法-⽜顿迭代法求平⽅根Q:Implement int sqrt(int x).Compute and return the square root of x.A:这⾥给出两种实现⽅法:⼀是⼆分搜索,⼆是⽜顿迭代法。
1. ⼆分搜索对于⼀个⾮负数n,它的平⽅根不会⼩于⼤于(n/2+1)(谢谢@linzhi-cs提醒)。
在[0, n/2+1]这个范围内可以进⾏⼆分搜索,求出n的平⽅根。
1 int sqrt(int x) {2 long long i = 0;3 long long j = x / 2 + 1;4 while (i <= j)5 {6 long long mid = (i + j) / 2;7 long long sq = mid * mid;8 if (sq == x) return mid;9 else if (sq < x) i = mid + 1;10 else j = mid - 1;11 }12 return j;13 }注:在中间过程计算平⽅的时候可能出现溢出,所以⽤long long。
2. ⽜顿迭代法为了⽅便理解,就先以本题为例:计算x2 = n的解,令f(x)=x2-n,相当于求解f(x)=0的解,如左图所⽰。
⾸先取x0,如果x0不是解,做⼀个经过(x0,f(x0))这个点的切线,与x轴的交点为x1。
同样的道理,如果x1不是解,做⼀个经过(x1,f(x1))这个点的切线,与x轴的交点为x2。
以此类推。
以这样的⽅式得到的x i会⽆限趋近于f(x)=0的解。
判断x i是否是f(x)=0的解有两种⽅法:⼀是直接计算f(x i)的值判断是否为0,⼆是判断前后两个解x i和x i-1是否⽆限接近。
经过(x i, f(x i))这个点的切线⽅程为f(x) = f(x i) + f’(x i)(x - x i),其中f'(x)为f(x)的导数,本题中为2x。
令切线⽅程等于0,即可求出x i+1=x i - f(x i) / f'(x i)。
牛顿迭代法解三元二次方程组(C++版)
牛顿迭代法解三元二次方程组(C++版)************************************************************************方程组为:Y1=-X1+0.3X2*X3-X3^2+0.6=0Y2=-0.1X1^2-X2 +0.8X1*X3-X3+0.4=0Y3=0.3X1-0.5X2^2 +0.7X1*X2-X3+0.5=0************************************************************************#include<fstream>#include<iostream>#include <iomanip>#include<cmath>#include <cstdlib>#define N 3 // 非线性方程组中变量个数及方程个数const int N2=N*N; // jacobi矩阵的元素个数#define eps 0.00001 // 收敛精度#define Max 2000 // 最大迭代次数using namespace std;double main(){double x0[N],y[N],x1[N],es,esmax,jacobi[N][N],aij;int i,j,k,it=0,iter=0;ofstream fpout1("d:\\Program Files\\Microsoft VisualStudio\\MyProjects\\xieFCZ\\x0.txt",ios::out);if(!fpout1){cout<<"fpout open fail!"<<endl;return 0; //打开文件失败则结束运行}ifstream fpin("d:\\Program Files\\Microsoft Visual Studio\\MyProjects\\xieFCZ\\X0.txt",ios::in); if(!fpin){cout<<"fpin open fail!"<<endl;return 0; //打开文件失败则结束运行ofstream fpout2("d:\\Program Files\\Microsoft Visual Studio\\MyProjects\\xieFCZ\\answer.txt",ios::out);if(!fpout2){cout<<"fpout open fail!"<<endl;return 0; //打开文件失败则结束运行}cout<<"********** Please input X0 ***********"<<endl;// 技巧一:为保证jacobi矩阵尽快收敛,初值最好在0 附近for(i=0;i<N;i++)cin>>x0[i];cout<<"输入的初值为:"<<endl;for(i=0;i<N;i++)cout<<x0[i]<<"\t";cout<<endl;fpout1<<"输入的初值为:"<<endl;do{ it++;for(i=0;i<N;i++)fpout1<<x0[i]<<"\t";fpout1<<endl;//jacobi have N2 element //计算jacobi矩阵的值jacobi[0][0]=0;jacobi[0][1]=0.3*x0[2];jacobi[0][2]=0.3*x0[1]-2*x0[2];jacobi[1][0]=-0.2*x0[0]+0.8*x0[2];jacobi[1][1]=0;jacobi[1][2]=0.8*x0[0]-1;jacobi[2][0]=0.3+0.7*x0[1];jacobi[2][1]=-x0[1]+0.7*x0[0];jacobi[2][2]=0;fpout2<<"第"<<it<<" 次jacobi矩阵是:"<<endl;for(i=0;i<N;i++){for(j=0;j<N;j++){fpout2.setf(cout.showpoint); //固定小数位数输出fpout2<<setprecision(8)<<jacobi[i][j]<<"\t";}fpout2<<endl;}fpout2<<endl;aij=0;for(i=0;i<N;i++) //计算jacobi矩阵元素的平方和aijfor(j=0;j<N;j++)aij=aij+jacobi[i][j]*jacobi[i][j];if(aij>1){cout<<"Sorry, aij>1"<<endl;k=rand()%3;x0[k]=((double)rand())/RAND_MAX;cout<<endl<<"由计算机第"<<it<<" 次随机产生初值:"<<endl;fpout1<<endl<<"由计算机第"<<it<<" 次随机产生初值:"<<endl;cout<<" ";for(i=0;i<N;i++)cout<<x0[i]<<"\t";cout<<endl;}}while(aij>1); //保证aij<1for(i=0;i<N;i++)x1[i]=x0[i];fpout2<<"*************** 牛顿迭代如下***************"<<endl;fpout2<<"迭代次数x1\t\t x2\t\t x3"<<endl<<endl;do{iter=iter+1;fpout2<<" "<<iter<<" "<<"\t";for(i=0;i<N;i++)fpout2<<x1[i]<<"\t";fpout2<<endl;//迭代格式y[0]=0.3*x1[1]*x1[2]-x1[2]*x1[2]+0.6;y[1]=-0.1*x1[0]*x1[0]+0.8*x1[0]*x1[2]-x1[2]+0.4;y[2]=0.3*x1[0]-0.5*x1[1]*x1[1]+0.7*x1[0]*x1[1]+0.5;//技巧二:由于要使最终的aij小于0,可让方程同除某个数使其系数小于1esmax=0.0;for(i=0;i<N;i++){es=y[i]-x1[i];if(fabs(es)>fabs(esmax))esmax=es;}if(fabs(esmax)<eps){fpout2<<endl<<endl<<"方程组的解为: "<<endl;cout<<endl<<endl<<"方程组的解为: "<<endl;for(i=0;i<N;i++){cout<<x1[i]<<"\t";fpout2<<x1[i]<<"\t";}cout<<endl<<endl;fpout2<<endl;break;}for(i=0;i<N;i++)x1[i]=y[i];}while(iter<Max);fpin.close();fpout1.close();fpout2.close();return 0;}(读入文件为x0.txt,输出文件为answer.txt)方程组的解为:0.26742924 -0.054130429 0.56862270将这个三个根人代入方程组计算,可知与0 的误差在±10^-6,这说明了计算机编程求代数方程得到的只是近似解。
牛顿迭代法解三元二次方程组(C++版)
牛顿迭代法解三元二次方程组(C++版)************************************************************************方程组为:Y1=-X1+0.3X2*X3-X3^2+0.6=0Y2=-0.1X1^2-X2 +0.8X1*X3-X3+0.4=0Y3=0.3X1-0.5X2^2 +0.7X1*X2-X3+0.5=0************************************************************************#include<fstream>#include<iostream>#include <iomanip>#include<cmath>#include <cstdlib>#define N 3 // 非线性方程组中变量个数及方程个数const int N2=N*N; // jacobi矩阵的元素个数#define eps 0.00001 // 收敛精度#define Max 2000 // 最大迭代次数using namespace std;double main(){double x0[N],y[N],x1[N],es,esmax,jacobi[N][N],aij;int i,j,k,it=0,iter=0;ofstream fpout1("d:\\Program Files\\Microsoft VisualStudio\\MyProjects\\xieFCZ\\x0.txt",ios::out);if(!fpout1){cout<<"fpout open fail!"<<endl;return 0; //打开文件失败则结束运行}ifstream fpin("d:\\Program Files\\Microsoft Visual Studio\\MyProjects\\xieFCZ\\X0.txt",ios::in); if(!fpin){cout<<"fpin open fail!"<<endl;return 0; //打开文件失败则结束运行ofstream fpout2("d:\\Program Files\\Microsoft Visual Studio\\MyProjects\\xieFCZ\\answer.txt",ios::out);if(!fpout2){cout<<"fpout open fail!"<<endl;return 0; //打开文件失败则结束运行}cout<<"********** Please input X0 ***********"<<endl;// 技巧一:为保证jacobi矩阵尽快收敛,初值最好在0 附近for(i=0;i<N;i++)cin>>x0[i];cout<<"输入的初值为:"<<endl;for(i=0;i<N;i++)cout<<x0[i]<<"\t";cout<<endl;fpout1<<"输入的初值为:"<<endl;do{ it++;for(i=0;i<N;i++)fpout1<<x0[i]<<"\t";fpout1<<endl;//jacobi have N2 element //计算jacobi矩阵的值jacobi[0][0]=0;jacobi[0][1]=0.3*x0[2];jacobi[0][2]=0.3*x0[1]-2*x0[2];jacobi[1][0]=-0.2*x0[0]+0.8*x0[2];jacobi[1][1]=0;jacobi[1][2]=0.8*x0[0]-1;jacobi[2][0]=0.3+0.7*x0[1];jacobi[2][1]=-x0[1]+0.7*x0[0];jacobi[2][2]=0;fpout2<<"第"<<it<<" 次jacobi矩阵是:"<<endl;for(i=0;i<N;i++){for(j=0;j<N;j++){fpout2.setf(cout.showpoint); //固定小数位数输出fpout2<<setprecision(8)<<jacobi[i][j]<<"\t";}fpout2<<endl;}fpout2<<endl;aij=0;for(i=0;i<N;i++) //计算jacobi矩阵元素的平方和aijfor(j=0;j<N;j++)aij=aij+jacobi[i][j]*jacobi[i][j];if(aij>1){cout<<"Sorry, aij>1"<<endl;k=rand()%3;x0[k]=((double)rand())/RAND_MAX;cout<<endl<<"由计算机第"<<it<<" 次随机产生初值:"<<endl;fpout1<<endl<<"由计算机第"<<it<<" 次随机产生初值:"<<endl;cout<<" ";for(i=0;i<N;i++)cout<<x0[i]<<"\t";cout<<endl;}}while(aij>1); //保证aij<1for(i=0;i<N;i++)x1[i]=x0[i];fpout2<<"*************** 牛顿迭代如下***************"<<endl;fpout2<<"迭代次数x1\t\t x2\t\t x3"<<endl<<endl;do{iter=iter+1;fpout2<<" "<<iter<<" "<<"\t";for(i=0;i<N;i++)fpout2<<x1[i]<<"\t";fpout2<<endl;//迭代格式y[0]=0.3*x1[1]*x1[2]-x1[2]*x1[2]+0.6;y[1]=-0.1*x1[0]*x1[0]+0.8*x1[0]*x1[2]-x1[2]+0.4;y[2]=0.3*x1[0]-0.5*x1[1]*x1[1]+0.7*x1[0]*x1[1]+0.5;//技巧二:由于要使最终的aij小于0,可让方程同除某个数使其系数小于1esmax=0.0;for(i=0;i<N;i++){es=y[i]-x1[i];if(fabs(es)>fabs(esmax))esmax=es;}if(fabs(esmax)<eps){fpout2<<endl<<endl<<"方程组的解为: "<<endl;cout<<endl<<endl<<"方程组的解为: "<<endl;for(i=0;i<N;i++){cout<<x1[i]<<"\t";fpout2<<x1[i]<<"\t";}cout<<endl<<endl;fpout2<<endl;break;}for(i=0;i<N;i++)x1[i]=y[i];}while(iter<Max);fpin.close();fpout1.close();fpout2.close();return 0;}(读入文件为x0.txt,输出文件为answer.txt)方程组的解为:0.26742924 -0.054130429 0.56862270将这个三个根人代入方程组计算,可知与0 的误差在±10^-6,这说明了计算机编程求代数方程得到的只是近似解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
牛顿迭代公式设r 是f(x) = 0的根,选取x0作为r 初始近似值,过点(x0,f(x0))f(x)的切线L ,L 的方程为y = f(x0)+f'(x0)(x-x0),求出L 与x 轴交点的横坐标 x1 = x0-f(x0)/f'(x0),称x1为r 的一次近似值。
过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x 轴交点的横坐标 x2 = x1-f(x1)/f'(x1),称x2为r 的二次近似值。
重复以上过程,得r 的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n)),称为r 的n+1次近似值,上式称为牛顿迭代公式。
解非线性方程f(x)=0似方法。
把f(x)在x0 f(x) = f(x0)+(x -x0)f'(x0)+(x -x0)^2*f''(x0)/2! +… 取其线性部分,作为非线性方程f(x) = 0的近似方程,即泰勒展开的前两项,则有f(x0)+f'(x0)(x -x0)-f(x)=0 设f'(x0)≠0则其解为x1=x0-f(x0)/f'(x0) 这样,得到牛顿法的一个迭代序列:x(n+1)=x(n)-f(x(n))/f'(x(n))。
牛顿迭代法又称牛顿切线法,它采用以下方法求根:先任意设定一个与真实的根接近的值x 0作为第一个近似根,由x 0求出f(x 0),过(x 0,f(x 0))点做f(x)的切线,交x 轴于x 1,把它作为第二次近似根,再由x 1求出f(x 1),再过(x 1,f(x 1))点做f(x)的切线,交x 轴于x 2,再求出f(x 2),再作切线……如此继续下去,直到足够接近真正的x *为止。
)()()()(0'0010100'x f x f x x x x x f x f -=-=因此,就是牛顿迭代公式。
例1 用牛顿迭代法求方程2x 3-4x 2+3x-6=0在1.5附近的根。
本题中,f(x)= 2x 3-4x 2+3x-6=((2x-4)x+3)x-6 f ’(x)= 6x 2-8x+3=(6x-8)x+3 #include "stdio.h"#include "math.h"void main(){ float x1,x0,f,f1;x1=1.5;do{ x0=x1;f=((2*x0-4)*x0+3)*x0-6;f1=(6*x0-8)*x0+3;x1=x0-f/f1;}while(fabs(x1-x0)>=1e-5);printf("THe root of equation is %5.2f\n",x1);}例题2 #include <math.h>main(){float x,x0,d,f,fd;x0=0;do {f=2*x0*x0*x0-4*x0*x0+3*x0-6;fd=6*x0*x0-8*x0+3;d=f/fd;x=x0-d;x0=x;}while(fabs(d)>1e-3);printf("x=%f\n",x); }X+=X-=X*X赋值表达式此表达式为自右向左赋值,如X的初值为12,此表达式赋值步骤如下:1.先进行“X-=X*X”的运算,它相当于X=X-X*X,X的值为12-144=-1322.再进行“X+=-132”的运算,相当于X=X+(-132),X的值为-132-132=-264。
直接选择排序的具体算法如下:选择排序(Selection Sort)的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕。
常用的选择排序方法有直接选择排序和堆排序。
void SelectSort(SeqList R){int i,j,k;for(i=1;i<n;i++){//做第i趟排序(1≤i≤n-1)k=i;for(j=i+1;j<=n;j++) //在当前无序区R[i..n]中选key最小的记录R[k]if(R[j].key<R[k].key)k=j; //k记下目前找到的最小关键字所在的位置if(k!=i){ //交换R[i]和R[k]R[0]=R[i];R[i]=R[k];R[k]=R[0];//R[0]作暂存单元} //endif} //endfor} //SeleetSort选择排序法选择排序的基本思想是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。
我们主要介绍简单选择排序、树型选择排序和堆排序。
简单选择排序的基本思想:第i趟简单选择排序是指通过n-i次关键字的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录进行交换。
共需进行i-1趟比较,直到所有记录排序完成为止。
例如:进行第i趟选择时,从当前候选记录中选出关键字最小的k号记录,并和第i个记录进行交换。
图9.5给出了一个简单选择排序示例,说明了前三趟选择后的结果。
图中大括号内为当前候选记录,大括号外为当前已经排好序的记录。
{ 48 62 35 77 55 14 35 98 }↑↑i k14 { 62 35 77 55 48 35 98 }↑↑i k 14 35 { 62 77 55 48 35 98 }↑↑i k 1435 35 {77 55 48 6298 }↑↑ i k 选择排序示例简单选择排序的算法具体描述如下:void SelectSort(RecordType r[], int length) /*对记录数组r做简单选择排序,length为数组的长度*/ { n=length; for ( i=1 ; i<= n-1; ++i){ k=i;for ( j=i+1 ; j<= n ; ++j) if (r[j].key < r[k].key ) k=j;if ( k!=i) { x= r[i];r[i]= r[k]; r[k]=x; } } } /* SelectSort */编辑本段[编辑本段]算法简单选择排序算法分析:在简单选择排序过程中,所需移动记录的次数比较少。
最好情况下,即待排序记录初始状态就已经是正序排列了,则不需要移动记录。
最坏情况下,即待排序记录初始状态是按逆序排列的,则需要移动记录的次数最多为3(n-1)。
简单选择排序过程中需要进行的比较次数与初始状态下待排序的记录序列的排列情况无关。
当i=1时,需进行n-1次比较;当i=2时,需进行n-2次比较;依次类推,共需要进行的比较次数是∑ =(n-1)+(n-2)+…+2+1=n(n-1)/2,即进行比较操作的时间复杂度为O(n2)。
选择排序法是对定位比较交换法的一种改进。
在讲选择排序法之前我们先来了解一下定位比较交换法。
为了便于理解,设有10个数分别存在数组元素a[0]~a[9]中。
定位比较交换法是由大到小依次定位a[0]~a[9]中恰当的值(和武林大会中的比武差不多),a[9]中放的自然是最小的数。
如定位a[0],先假定a[0]中当前值是最大数,a[0]与后面的元素一一比较,如果a[4]更大,则将a[0]、a[4]交换,a[0]已更新再与后面的a[5]~a[9]比较,如果a[8]还要大,则将a[0]、a[8]交换,a[0]又是新数,再与a[9]比较。
一轮比完以后,a[0]就是最大的数了,本次比武的武状元诞生了,接下来从a[1]开始,因为状元要休息了,再来一轮a[1]就是次大的数,也就是榜眼,然后从a[2]开始,比出探花,真成比武大会了,当比到a[8]以后,排序就完成了。
下面给大家一个例子:main(){int a[10];int i,j,t;for ( i = 0; i < 10; i ++ ) scanf("%d",&a[ i ]); /*输入10个数,比武报名,报名费用10000¥^_^*/for ( i = 0; i < 9; i ++ )for ( j = i + 1; j < 10; j ++)if ( a[ i ] < a[ j ] ) { t = a[ i ]; a[ i ] = a[ j ]; a[ j ] = t; } /*打不过就要让出头把交椅,不过a[ i ]比较爱面子,不好意思见 a[ j ],让t帮忙*/for( i = 0; i < 10; i ++) printf("%4d",a[ i ]); /*显示排序后的结果*/ }好啦,啰嗦了半天总算把定位比较排序法讲完了,这个方法不错,容易理解,就是有点麻烦,一把椅子换来换去,哎~所以就有了下面的选择排序法,开始的时候椅子谁也不给,放在一边让大家看着,找个人k记录比赛结果,然后发椅子。
具体来讲呢就是,改进定位比较排序法,但是这个改进只是一部分,比较的次数没变,该怎么打还是怎么打,就是不用换椅子了。
每次外循环先将定位元素的小标i值记录到K,认为a[k]是最大元素其实k=i还是a[ i ]最大,a[k]与后面的元素一一比较,该交换的也是也不换,就是把K的值改变一下就完了,最后在把a[k]与a[ i ]交换,这样a就是最大的元素了。
然后进入下一轮的比较。
选择排序法与定位比较排序法相比较,比的次数没变,交换的次数减少了。
下面也写个例子:由大到小时:main(){int a[10];int i,j,t,k;for ( i = 0; i < 10; i ++ ) scanf("%d",&a[ i ]); /*输入10个数,比武报名,报名费用10000¥ ^_^*/for ( i = 0; i < 9; i ++ ){ k = i; /*裁判AND记者实时追踪报道比赛情况*/for ( j = i + 1; j < 10; j ++)if ( a[ k ] < a[ j ] ) k = j;if (k!=i)t = a[ i ]; a[ i ] = a[ k ]; a[ k ] = t; /* t 发放奖品*/ }for( i = 0; i < 10; i ++) printf("%4d",a[ i ]); /*显示排序后的结果*/}由小到大时:main(){int a[10];int i,j,t,k;for ( i = 0; i < 10; i ++ ) scanf("%d",&a[ i ]); /*输入10个数,比武报名,报名费用10000¥ ^_^*/for ( i = 0; i < 9; i ++ ){ k = i; /*裁判AND记者实时追踪报道比赛情况*/for ( j = i + 1; j < 10; j ++)if ( a[ k ] < a[ j ] ) k = j;if (k!=i)t = a[ i ]; a[ i ] = a[ k ]; a[ k ] = t; /* t 发放奖品*/ }for( i = 9; i >= 0; i --) printf("%4d",a[ i ]); /*显示排序后的结果*/}冒泡排序是每一次都可能要交换而选择排序是在比较时记下a[i]的位置最后来交换所以他们的交换过程是不一样的而查找的过程是一样的效率不会比冒泡的低...。