对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。[1]

中文名

二分法

外文名

Bisection method概    念

一分为二的方法

见载刊物

《心理学名词》 科学出版社

公布时间

1999年[4]

二分法定义

编辑

语音

二分法(Bisection method) 即一分为二的方法. 设[a,b]为R的闭区间. 逐次二分法就是造出如下的区间序列([an,bn]):a0=a,b0=b,且对任一自然数n,[an+1,bn+1]或者等于[an,cn],或者等于[cn,bn],其中cn表示[an,bn]的中点.[2]

二分法典型算法

编辑

语音

算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。

基本思想:假设数据是按升序排序的,对于给定值key,从序列的中间位置k开始比较,

如果当前位置arr[k]值等于key,则查找成功;

若key小于当前位置值arr[k],则在数列的前半段中查找,arr[low,mid-1];

若key大于当前位置值arr[k],则在数列的后半段中继续查找arr[mid+1,high],

直到找到为止,时间复杂度:O(log(n))[3]

二分法求法

编辑

语音

给定精确度ξ,用二分法求函数f(x)零点近似值的步骤如下:

1 确定区间[a,b],验证f(a)·f(b)<0,给定精确度ξ.

2 求区间(a,b)的中点c.

3 计算f(c).

(1) 若f(c)=0,则c就是函数的零点;

(2) 若f(a)·f(c)<0,则令b=c;

(3) 若f(c)·f(b)<0,则令a=c.

(4) 判断是否达到精确度ξ:即若|a-b|

二分法计算机应用

编辑

语音

由于计算过程的具体运算复杂,但每一步的方式相同,所以可通过编写程序来运算。

Java语言

public int binarySearch(int[] data,int aim){//以int数组为例,aim为需要查找的数

int start = 0;

int end = data.length-1;

int mid = (start+end)/2;//a

while(data[mid]!=aim&&end>start){//如果data[mid]等于aim则死循环,所以排除

if(data[mid]>aim){

end = mid-1;

}else if(data[mid]

start = mid+1;

}

mid = (start+end)/2;//b,注意a,b

}

return (data[mid]!=aim)?-1:mid;//返回结果

}//针对已经排序好的数组进行查找(对上面代码进行的改进)

publicstaticbooleanbinarySearch(int[]array,inttarget){

intleft=0;

intright=array.length-1;

intmid=(left+right)/2;

while(array[mid]!=target&&right>left){

if(array[mid]>target){

right=mid-1;

}

elseif(array[mid]

left=mid+1;

}

mid=(left+right)/2;

//判断在缩小范围后,新的left或者right是否会将target排除

if(array[right]

break;//若缩小后right比target小,即target不在数组中

}

elseif(array[left]>target){

break;//若缩小后left比target大,即target不在数组中

}

}

return(array[mid]==target);

}

C语言

方程式为:f(x) = 0,示例中f(x) = 1+x-x^3

使用示例:

input a b e: 1 2 1e-5

solution: 1.32472

源码如下:#include

#include

#include

#include

double f(double x)

{

return 1+x-x*x*x;

}

int main()

{

double a = 0, b = 0, e = 1e-5;

printf("input a b e: ");

scanf("%lf%lf%lf", &a, &b, &e);

e = fabs(e);

if (fabs(f(a)) <= e)

{

printf("solution: %lg\n", a);

}

else if (fabs(f(b)) <= e)

{

printf("solution: %lg\n", b);

}

else if (f(a)*f(b) > 0)

{

printf("f(%lg)*f(%lg) > 0 ! need <= 0 !\n", a, b);

}

else

{

while (fabs(b-a) > e)

{

double c = (a+b)/2.0;

if (f(a)* f ( c )

b = c;

else

a = c;

}

printf("solution: %lg\n", (a+b)/2.0);

}

return 0;

}

C++语言

[类C编写].

|f(x)|<10^-5 f(x)=2x^3-4x^2+3x-6#include

#include

using namespace std;

double f(double x);

const double Accu = pow(10.0, -5.0); // define accuracy

int main()

{

double a, b, c;

a = b = c = 0;

do

{

cout <

cin >> a >> b;

} while (!cin || f(a) * f(b) >= 0); // bad input or f(a) * f(b) >= 0

do

{

c = (a + b) / 2.0; // c is the average number of a and b

if (f(a) * f(c)

b = c;

else if (f(b) * f(c)

a = c;

else

break;

} while ( abs(f(c)) > Accu); // if deviation is smaller than pow(10.0, -5.0)

cout <

return 0;

}

double f(double x)

{

return (2 * x * x * x - 4 * x * x + 3 * x - 6); // or 2 * pow(x, 3.0) - 4 * pow(x, 2.0) + 3 * x - 6

}

C++语言中的二分查找法

算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的。

基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。

假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2.

1.开始令front=0(指向3),end=7(指向88),则mid=3(指向36)。因为mid>x,故应在前半段中查找。

2.令新的end=mid-1=2,而front=0不变,则新的mid=1。此时x>mid,故确定应在后半段中查找。

3.令新的front=mid+1=2,而end=2不变,则新的mid=2,此时a[mid]=x,查找成功。

如果要查找的数不是数列中的数,例如x=25,当第三次判断时,x>a[mid],按以上规律,令front=mid+1,即front=3,出现front>end的情况,表示查找不成功。

例:在有序的有N个元素的数组中查找用户输进去的数据x。

算法如下:

1.确定查找范围front=0,end=N-1,计算中项mid(front+end)/2。

2.若a[mid]=x或front>=end,则结束查找;否则,向下继续。

3.若a[mid]x,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给end,并重新计算mid,转去执行步骤2。

代码:

#include

#define N 10

using namespace std;

int main()

{

int a[N],front,end,mid,x,i;

cout<

for(i=0;i

cin>>a[i];

cout<

cin>>x;

front=0;

end=N-1;

mid=(front+end)/2;

while(front

{

if(a[mid]

if(a[mid]>x)end=mid-1;

mid=front + (end - front)/2;

}

if(a[mid]!=x)

cout<

else

cout<

return 0;

}

MATLAB语言

function y=f(x)

y=f(x); %函数f(t)的表达式

i=0; %二分次数记数

a=a; %求根区间左端

b=b; %求根区间右端

fa=f(a); %计算f(a)的值

fb=f(b); %计算f(b)的值

c=(a+b)/2; %计算区间中点

fc=f(c); %计算区间中点f(c)

while abs(fc)>=ε; %判断f(c)是否为零点

if fa*fc>=0; %判断左侧区间是否有根

fa=fc;

a=c;

else fb=fc;

b=c;

end

c=(a+b)/2;

fc=f(c);

i=i+1;

end

fprintf('\n%s%.6f\t%s%d',c,'迭代次数i=',i) %计算结果输出

快速排序伪代码(非随机)

下面的过程实现快速排序:

QUICKSORT(A,p,r)

1 ifp

2 thenq ← PARTITION(A,p,r)

3 QUICKSORT(A,p,q-1)

4 QUICKSORT(A,q+1,r)

为排序一个完整的数组A,最初的调用是QUICKSORT(A,1,length[A])。

快速排序算法的关键是PARTITION过程,它对子数组A[p..r]进行就地重排:

PARTITION(A,p,r)

1 x← A[r]

2 i← p-1

3 forj← ptor-1

4 do ifA[j]≤x

5 theni ← i+1

6 exchange A[i]←→A[j]

7 exchange A[i+1]←→A[r]

8 returni+1

快速排序伪代码(随机)

对PARTITION和QUICKSORT所作的改动比较小。在新的划分过程中,我们在真正进行划分之前实现交换:

(其中PARTITION过程同快速排序伪代码(非随机))

RANDOMIZED-PARTITION(A,p,r)

1 i ← RANDOM(p,r)

2 exchange A[r]←→A[i]

3 return PARTITION(A,p,r)

新的快速排序过程不再调用PARTITION,而是调用RANDOMIZED-PARTITION。

RANDOMIZED-QUICKSORT(A,p,r)

1 ifp

2 thenq ← RANDOMIZED-PARTITION(A,p,r)

3 RANDOMIZED-QUICKSORT(A,p,q-1)

4 RANDOMIZED-QUICKSORT(A,q+1,r)

Pascal,递归快排1

procedure work(l,r: longint);

var i,j,tmp: longint;

begin

if l

i:=l;j:=r;tmp:=stone[i];

while i

begin

while (i

if(i

begin

stone[i]:=stone[j];

inc(i);

end;

while (istone[i])do inc(i);

if i

begin

stone[j]:=stone[i];

dec(j);

end;

end;

stone[i]:=tmp;

work(l,i-1);

work(i+1,r);

end;

end;//本段程序中stone是要排序的数组,从小到大排序,stone数组为longint(长整型)类型。在主程序中的调用命令为“work(1,n);”不含引号。表示将stone数组中的1到n号元素进行排序。

Pascal,递归快排2

Program quiksort;

//快速排序法

const max=100;

var n:integer;

a:array[1..max] of longint;

procedure sort(l,r: longint);

var i,j,x,y: longint;

begin

i:=l; j:=r; x:=a[(l+r) div 2];

repeat

while a[i]

while x

if i<=j then

begin

y:=a[i]; a[i]:=a[j]; a[j]:=y;

inc(i); dec(j);

end;

until i>j;

if l

if i

end;

begin

//生成数组;

randomize;

for n:=1 to max do

begin

a[n]:=random(1000);

write(a[n]:5);

end;

writeln;

//排序

sort(1,max);

//输出

for n:=1 to max do write(a[n]:5);writeln;

end.

Delphi 递归快排3

type

TNTA=array of integer;

var

A:TNTA;

procedure QuicSort(var Arr:TNTA;AStart,AEnd:Integer);

var

I,J,Sign:integer;

procedure Switch(A,B:Integer);

var

Tmp:Integer;

begin

Tmp:=Arr[A];

Arr[A]:=Arr[B];

Arr[B]:=Tmp;

end;

begin

if AEnd<=AStart then

Exit;

Sign:=(AStart+AEnd)div 2;

{Switch value}

Switch(Sign,AEnd);

{Start to sort}

J:=AStart;

for I := AStart to AEnd-1 do

begin

if (Arr[I]J)} then

begin

Switch(J,I);

Inc(J);

end;

end;

Switch(J,AENd);

QuicSort(Arr,AStart,J);

QuicSort(Arr,J+1,AEnd);

end;

procedure TForm1.btn1Click(Sender: TObject);

const

LEN=10000;

var

I: Integer;

Start:Cardinal;

begin

SetLength(A,LEN);

Randomize;

for I := Low(A) to High(A) do

A[I]:=Random(LEN*10);

Start:=GetTickCount;

QuicSort(A,Low(A),High(A));

ShowMessageFmt('%d large quick sort take time:%d',[LEN,GetTickCount-Start]);

end;

Pascal,非递归快排1

var

s:packed array[0..100,1..7]of longint;

t:boolean;

i,j,k,p,l,m,n,r,x,ii,jj,o:longint;

a:packed array[1..200000]of longint;

function check:boolean;

begin

if i>2 then exit(false);

case i of

1:if (s[k,3]

2:if s[k,1]

end;

exit(false);

end;

procedure qs; //非递归快速排序

begin

k:=1;

t:=true;

s[k,1]:=1;

s[k,2]:=n;

s[k,3]:=1;

while k>0 do

begin

r:=s[k,2];

l:=s[k,1];

ii:=s[k,3];

jj:=s[k,4];

if t then

if (r-l>30) then

begin

x:=a[(r-l+1)shr 1 +l];

ii:=s[k,1];jj:=s[k,2];

repeat

while a[ii]

while a[jj]>x do dec(jj);

if ii<=jj then

begin

m:=a[ii];

a[ii]:=a[jj];

a[jj]:=m;

inc(ii);dec(jj);

end;

until ii>jj;

s[k,3]:=ii;

s[k,4]:=jj;

end

else begin

for ii:=l to r do

begin

m:=a[ii];jj:=ii-1;

while (m

begin

a[jj+1]:=a[jj];

dec(jj);

end;

a[jj+1]:=m;

end;

t:=false; dec(k);

end;

if t then

for i:=1 to 3 do

if check then break;

if not t then

begin

i:=s[k,5];

repeat

inc(i);

until (i>2)or check;

end;

if i>2 then begin t:=false; dec(k);end

else t:=true;

if t then

begin

s[k,5]:=i;

inc(k);

case i of

1:begin s[k,1]:=s[k-1,3];s[k,2]:=s[k-1,2];end;

2:begin s[k,1]:=s[k-1,1];s[k,2]:=s[k-1,4];end;

end;

end;

end;

end;

begin

readln(n);

for i:=1 to n do read(a[i]);

k:=1;

qs;

for i:=1 to n do //输出

write(a[i],' ');

writeln;

end.

经测试,非递归快排比递归快排快。

Pascal,非递归快排2

//此段快排使用l队列储存待处理范围

var

a:Array[1..100000] of longint;

l:Array[1..100000,1..2] of longint;

n,i:longint;

procedure fs;//非递归快排

var

s,e,k,j,ms,m:longint;

begin

s:=1;e:=1;l[1,1]:=1;l[1,2]:=n;

while s<=e do

begin

k:=l[s,1];j:=l[s,2];m:=random(j-k+1)+k;

ms:=a[m];a[m]:=a[k];

while k

begin

while (kms) do dec(j);

if k

while (k

if k

end;

a[k]:=ms;

if l[s,1]

if j+1

inc(s);

end;

end;

begin

randomize;

read(n);

for i:=1 to n do read(a[i]);

fs;

for i:=1 to n do write(a[i],' ');

end.

实战

Problem:大整数开方 NOIP2011普及组初赛完善程序第二题

题目描述

输入一个正整数n(1

代码

Const

SIZE = 200;

Type

hugeint = Record

len : Integer;

num : Array[1..SIZE] Of Integer;

End;

//len表示大整数的位数;num[1]表示个位、num[2]表示十位,以此类推

Var

s : String;

i : Integer;

target, left, middle, right : hugeint;

Function times(a, b : hugeint) : hugeint;

// 计算大整数 a 和 b 的乘积

Var

i, j : Integer;

ans : hugeint;

Begin

FillChar(ans, SizeOf(ans), 0);

For i := 1 To a.len Do

For j := 1 To b.len Do

ans.num[i + j - 1] := ans.num[i + j - 1] + a.num[i] * b.num[j];

For i := 1 To a.len + b.len Do

Begin

ans.num[i + 1] := ans.num[i + 1] + ans.num[i] DIV 10;

ans.num[i] := ans.num[i] mod 10;

If ans.num[a.len + b.len] > 0

Then ans.len := a.len + b.len

Else ans.len := a.len + b.len - 1;

End;

times := ans;

End;

Function add(a, b : hugeint) : hugeint;

// 计算大整数 a 和 b 的和

Var

i : Integer;

ans : hugeint;

Begin

FillChar(ans.num, SizeOf(ans.num), 0);

If a.len > b.len

Then ans.len := a.len

Else ans.len := b.len;

For i := 1 To ans.len Do

Begin

ans.num[i] :=ans.num[i] + a.num[i] + b.num[i];

ans.num[i + 1] := ans.num[i + 1] + ans.num[i] DIV 10;

ans.num[i] := ans.num[i] MOD 10;

End;

If ans.num[ans.len + 1] > 0

Then Inc(ans.len);

add := ans;

End;

Function average(a, b : hugeint) : hugeint;

// 计算大整数 a 和 b 的平均数的整数部分

Var

i : Integer;

ans : hugeint;

Begin

ans := add(a, b);

For i := ans.len DownTo 2 Do

Begin

ans.num[i - 1] := ans.num[i - 1] + (ans.num[i] mod 2) * 10;

ans.num[i] := ans.num[i] DIV 2;

End;

ans.num[1] := ans.num[1] DIV 2;

If ans.num[ans.len] = 0

Then Dec(ans.len);

average := ans;

End;

Function plustwo(a : hugeint) : hugeint;

// 计算大整数 a 加 2 后的结果

Var

i : Integer;

ans : hugeint;

Begin

ans := a;

ans.num[1] := ans.num[1] + 2;

i := 1;

While (i <= ans.len) AND (ans.num[i] >= 10) Do

Begin

ans.num[i + 1] := ans.num[i + 1] + ans.num[i] DIV 10;

ans.num[i] := ans.num[i] MOD 10;

Inc(i);

End;

If ans.num[ans.len + 1] > 0

Then inc(ans.len);

plustwo := ans;

End;

Function over(a, b : hugeint) : Boolean;

// 若大整数 a > b 则返回 1, 否则返回 0

Var

i : Integer;

Begin

If (a.len

Begin

over := FALSE;

Exit;

End;

If a.len > b.len Then

Begin

over := TRUE;

Exit;

End;

For i := a.len DownTo 1 Do

Begin

If a.num[i] < b.num[i] Then

Begin

over := FALSE;

Exit;

End;

If a.num[i] > b.num[i] Then

Begin

over := TRUE;

Exit;

End;

End;

over := FALSE;

End;

Begin

Readln(s);

FillChar(target.num, SizeOf(target.num), 0);

target.len := Length(s);

For i := 1 To target.len Do

target.num[i] := Ord(s[target.len - i + 1]) - ord('0');

FillChar(left.num, SizeOf(left.num), 0);

left.len := 1;

left.num[1] := 1;

right := target;

Repeat

middle := average(left, right);

If over(times(middle, middle), target)

Then right := middle

Else left := middle;

Until over(plustwo(left), right);

For i := left.len DownTo 1 Do

Write(left.num[i]);

Writeln;

End.

词条图册

更多图册

参考资料

1.

王朝银.步步高.新课标.高考总复习.数学.文科.哈尔滨:黑龙江教育出版社,2011

2.

[法]L·Chambadal;吴越恩,叶厚荣;刘光旭,戚征.数学词典:高等教育出版社,1989-07

3.

思想/表达二分法的检讨

.中国知网[引用日期2017-04-15]

4.

二分法

.911查询[引用日期2021-07-08]

二分法的计算机应用,二分法(数学领域术语)_百度百科相关推荐

  1. 用计算机计算的定义,计算(数学用语)_百度百科

    计算,数学用语,是一种将单一或复数之输入值转换为单一或复数之结果的一种思考过程.[1] 中文名 计算外文名 calculate 适用范围 数理科学 计算定义 编辑 语音 计算的定义有许多种使用方式,有 ...

  2. 路西法效应_百度百科

    路西法效应_百度百科 路西法效应_百度百科 路西法效应     求助编辑百科名片     路西法效应      路西法效应 社会科学工作者很少使用"善"."恶" ...

  3. 北京方家胡同46号_百度百科

    北京方家胡同46号_百度百科 北京方家胡同46号         简介     方家胡同46号院即原中国机床厂的厂址,占地面积9000平方米,现有建筑面积约13000平方米,是北京工业史上重要的&qu ...

  4. 为什么放弃治疗_百度百科

    为什么放弃治疗_百度百科 为什么放弃治疗

  5. 弗拉明戈舞_百度百科

    弗拉明戈舞_百度百科 弗拉明戈舞     编辑     弗拉明戈舞简介"弗拉明戈"不仅是歌(cante).舞(baile)和吉他音乐(toque)的三合一艺术,也代表着一种慷慨.狂 ...

  6. QS世界大学排名_百度百科

    QS世界大学排名_百度百科 莱斯特大学

  7. 你若安好便是晴天_百度百科

    你若安好便是晴天_百度百科 你若安好便是晴天 这是一个多义词,请在下列义项中选择浏览 1.人物传记2.杨钰莹原唱歌曲3.蝴蝶季言情小说 林徽因,一代风华的绝世佳人,才华横溢倾倒众生:让徐志摩.梁思成. ...

  8. 九头身美女_百度百科

    九头身美女_百度百科 九头身美女

  9. 讷于言而敏于行_百度百科

    讷于言而敏于行_百度百科 讷于言而敏于行编辑

  10. 探索者系列_百度百科

    探索者系列_百度百科 探索者系列

最新文章

  1. vue-vue项目中mock.js的使用
  2. Linux 认证考试:精解Linux find命令的使用linuxfindnam
  3. mac升级php7,MAC更新自带php版本到7.0
  4. JQUERY解析XML IE8的兼容问题
  5. 《企业软件交付:敏捷与高效管理精要》——2.2 MyCo公司和MyProj企业软件交付项目...
  6. 小学期Deadline之GEC6818点奶茶系统
  7. STM32F407——SYN6288语音播报模块串口一修改为串口三
  8. 拟合函数未知数个数与用于拟合的序列点数的关系
  9. 2022东南大学网安916考研经验贴
  10. 异常:Activity has leaked window com.android.internal.policy.impl.PhoneWindow
  11. Linux 驱动开发 六十六:多点触控(MT)协议
  12. 分布式电商项目五:使用人人开源搭建前后分离的后台管理系统
  13. 1162: 6003 星期几?
  14. Ubuntu 下软件列表
  15. 网页三剑客,html/css/javascript
  16. 十种常用算法之分治算法(java版)
  17. Vue 项目导入字体文件
  18. 精密整流电路(AD630)
  19. 使用Gitbook Editor编辑gitbook电子书
  20. 在ABAQUS中如何使用修正DPC帽盖模型

热门文章

  1. MySQL优化常见Extra分析——慢查询优化
  2. python常用模块之requests
  3. 112. Path Sum
  4. [转]WinForm--使用C#制做进程监视器
  5. Android PopupWindow系列 (一) —— popupWindow基本使用方略
  6. 一组匹配中国大陆手机号的正则表达式
  7. layui 表格点击图片放大
  8. CSS 选择器优先级
  9. mobile web页面调试方法
  10. 第3章 变量和表达式