当前位置:文档之家› C语言编程_牛顿迭代法求方程2

C语言编程_牛顿迭代法求方程2

牛顿迭代公式设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]的位置最后来交换所以他们的交换过程是不一样的而查找的过程是一样的效率不会比冒泡的低...。

相关主题