QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2835|回复: 0
打印 上一主题 下一主题

[讨论]一道分治法的题目,仅供参考

[复制链接]
字体大小: 正常 放大
lllaaa        

2

主题

2

听众

27

积分

升级  23.16%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-9-29 19:02 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
< ><FONT face="Times New Roman">2-2</FONT>、下面的<FONT face="Times New Roman">7</FONT>个算法与本章中的二分搜索算法<FONT face="Times New Roman">binarySearch</FONT>略有不同。请判断这<FONT face="Times New Roman">7</FONT>个算法的正确性。如果算法不正确,请说明错误产生的原因。如果算法正确,请给出算法的正确性证明。</P>  B" B1 B7 D% n+ W/ A
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>6 z$ C. {) }8 w. s: _
< ><FONT face="Times New Roman">{</FONT></P>' R" h3 {4 ?2 j; H, n
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>; {+ y" P) s! E3 x7 I0 B) a4 `$ i
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>4 F* B$ I+ Y3 @  A( U% V
< ><FONT face="Times New Roman">{</FONT></P>. Y& Z: f3 g! P) @5 V: I
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>; r  ]. n7 L% Z4 {" Y
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>' _5 @4 X$ }' p
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
: k: B/ x- p; ^. M; ^. z! E< ><FONT face="Times New Roman">   else right = middle;</FONT></P>6 t9 r0 {5 {  Y) `0 a/ ]3 j+ ^
< ><FONT face="Times New Roman">}//while</FONT></P>( s% B2 X- X8 O! H7 r" Z7 f3 c
< ><FONT face="Times New Roman">return –1;</FONT></P>
; [: B, K/ z: \6 m< ><FONT face="Times New Roman">}</FONT></P>% \  y$ g3 x! W! q1 `2 C7 P$ l  i, @
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>0 e; R; F0 N  G$ l
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
$ P4 y6 r9 d- E, L! D8 f* G< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>+ S9 w0 j& O0 ]
< ><FONT face="Times New Roman">{</FONT></P>3 Y9 w/ G1 J& \+ O' J  {
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>3 Y4 g* O% y2 X( r/ o
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>. K1 a$ F1 `1 E
< ><FONT face="Times New Roman">{</FONT></P>/ d4 p+ k. D1 E, H  U* k' m" [3 k
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>/ y2 a/ [! e0 x$ s- L" h
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>& j  T0 z- y; p& T; B, b
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>8 |$ d. r! c) Y: J5 J
< ><FONT face="Times New Roman">}//while</FONT></P>
9 }7 t/ n7 \5 @* r2 G" n' o< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>9 m  J2 x0 r, @6 f' B
< ><FONT face="Times New Roman">else return –1;</FONT></P>/ e& F" f4 [" ^3 D9 Y: T; k
< ><FONT face="Times New Roman">}</FONT></P>$ e& G3 G7 t: `
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>1 ?9 c" S  }' l
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* @6 d9 P3 |6 E: [( \4 d& N
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>) {# u" X+ D6 T, `/ U. n
<P ><FONT face="Times New Roman">{</FONT></P>
9 ?! U" A0 M2 H% X<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
1 K  @1 N) l9 g# t; A1 K3 W<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
8 V3 G7 Q7 }& q6 |1 E& h<P ><FONT face="Times New Roman">{</FONT></P>, `  f0 r1 V6 V0 D8 [/ ~! v; [" [
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>3 K9 [, q# O1 |: I  q4 N
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
5 D' H% o4 p' c9 E3 m0 C<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
* U+ U9 b; F9 M+ A6 r# o" B<P ><FONT face="Times New Roman">}//while</FONT></P>7 _# T% @& E! Y7 ~) l' A; Y
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>( T+ T% v: R% b: h/ r
<P ><FONT face="Times New Roman">else return –1;</FONT></P>5 y0 s% u4 A3 ?1 q
<P ><FONT face="Times New Roman">}</FONT></P>7 F4 b9 x/ }  X8 D7 G- A4 f
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% V4 ~; U: |3 d* _& g! a6 S
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, m0 O) J9 A  A/ z* S<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
( I5 p; [( X' f# y! Z& V<P ><FONT face="Times New Roman">{</FONT></P>5 B5 V9 d+ }/ p3 x% i7 Q7 D  [
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>) Y) ?( H; f  E. k1 l
<P ><FONT face="Times New Roman">              {</FONT></P>6 M$ P! K* K0 V4 D3 }* e
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
; m4 Y! n0 k* O0 ]' x<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>6 h  P4 M3 T+ j. D7 O
<P ><FONT face="Times New Roman">              {</FONT></P>6 z$ G# m$ d6 R- u8 \4 r6 y
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
4 m; v7 W$ ^: n4 o$ L, W<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>. o) b& z9 v* T' G' S
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
1 D, i- S$ l2 L6 p* [<P ><FONT face="Times New Roman">}//while</FONT></P>
% w( D, `- [3 G9 i$ ^<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>/ u& N! s2 H7 |8 H
<P ><FONT face="Times New Roman">}//if</FONT></P>( {6 ?4 g8 t5 c/ J
<P ><FONT face="Times New Roman">return –1;</FONT></P>
/ ^7 b" t) P  {<P ><FONT face="Times New Roman">}</FONT></P>
$ ?- J& s3 g5 ^: a. w* T2 ^- r0 a<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  t: d+ E+ _# z
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( X1 ^- _7 z) {! {2 ^
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
, g; b# y8 |; e<P ><FONT face="Times New Roman">{</FONT></P>7 P$ I: w$ T+ b
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
. U1 g2 H1 A! j; d9 s9 ^) B8 g  I# U<P ><FONT face="Times New Roman">              {</FONT></P>
4 E; x% Z+ r% o; A0 F+ f1 f3 I6 O<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
7 V+ z3 j& u4 X, H4 s( L<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
  r5 U9 E& O- L# I<P ><FONT face="Times New Roman">              {</FONT></P>- z5 E) [# `! u
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>* s+ u2 f8 h; _0 y
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
; k' H7 h  D1 A/ B# _1 W<P ><FONT face="Times New Roman">else left = middle;</FONT></P>/ \% u- Y/ ?( r4 d0 R! y& V1 P
<P ><FONT face="Times New Roman">}//while</FONT></P>
0 Y3 }, F5 ]) s- A8 D' l! {; M<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>. T, {- A. `) E
<P ><FONT face="Times New Roman">}//if</FONT></P>2 g4 Z% e+ F/ \" T6 B9 [# A
<P ><FONT face="Times New Roman">return –1;</FONT></P>
' H% M% d9 e0 D5 F) i8 |<P ><FONT face="Times New Roman">}</FONT></P>: ^/ y9 a- r. i5 k" X) U" w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" K$ x* o7 i+ f0 Y6 b" i<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. w/ a6 m) y4 m! W( s<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
1 d% E+ J8 K6 V<P ><FONT face="Times New Roman">{</FONT></P>
" b/ u3 @5 l" q* |$ X7 U<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
2 J/ E9 ^6 P7 H5 t* D<P ><FONT face="Times New Roman">              {</FONT></P>
1 g6 a  ]( V9 @& ^' r) o2 A<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>4 L! U; ~$ }2 R8 w' _/ h" x
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>+ V2 \- |8 L. Q& Y8 A  F! O1 H
<P ><FONT face="Times New Roman">              {</FONT></P>2 {. C3 A( f9 P# q/ W9 K
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>& |3 f  a, x$ u/ |) }! Q
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>* J2 Z1 e' v  [+ ^( ~
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
9 [$ h& y  M! W- O  K<P ><FONT face="Times New Roman">}//while</FONT></P>' b+ t% i, b; i
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
3 Z/ v' o; `' M: }$ e% |; h7 @<P ><FONT face="Times New Roman">}//if</FONT></P>% [$ o. ?. R2 m) [* g
<P ><FONT face="Times New Roman">return –1;</FONT></P>
. n5 Y3 w4 x3 D/ X  g<P ><FONT face="Times New Roman">}</FONT></P>! b7 H8 t: o8 j( M8 r3 t- f1 s! F
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) [: M* y' U7 R9 |$ H
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 `* T! B- a8 k: i
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>; s/ J0 w" @% G
<P ><FONT face="Times New Roman">{</FONT></P>
' V* ~- y- B: ~- d! N' N<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
* Z* m: T% K. {0 ~$ Y- l<P ><FONT face="Times New Roman">              {</FONT></P>
9 o7 n5 i9 ?( K3 z) _7 N) H<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
( S; @3 j. m' q<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
+ q" k7 }4 x5 f# B0 N. G, a<P ><FONT face="Times New Roman">              {</FONT></P>
' u3 S4 _& A/ q2 R<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
( F8 G6 I# o5 i- O<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>7 A7 j% x, j; U- q
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>& t$ A7 _" |8 Z" q
<P ><FONT face="Times New Roman">}//while</FONT></P>
0 P( n6 d) K% H5 l, y% G5 Z+ S<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>! z, s9 w4 F* _, Y8 f' y- i( d
<P ><FONT face="Times New Roman">}//if</FONT></P>
# H7 i8 Y" j( y<P ><FONT face="Times New Roman">return –1;</FONT></P>& T$ I6 @- Z! m: A( I, D! s
<P ><FONT face="Times New Roman">}</FONT></P>
' J+ R  [. L2 V" V<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ d2 ?1 a/ c, q<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
; Q2 I! J. r) U6 G! Z<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>; |: e3 |$ K, v# {0 K& S
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
# O; ~& G* |9 F! L, N0 ~3 T<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>' Z) v: u* I$ u5 K2 e1 n# L: C' Z
<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
: B" W- ?; ~* F/ ]1 U) L( p<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
, m( u7 f+ \0 S/ N1 n1 J<P >当<FONT face="Times New Roman">n</FONT>≥<FONT face="Times New Roman">2</FONT>时,如果条件<FONT face="Times New Roman">x = a[n-1] </FONT>且<FONT face="Times New Roman"> a[n-2] </FONT>≠<FONT face="Times New Roman"> a[n-1]</FONT>成立,则必将在某一步之后出现<FONT face="Times New Roman">x = a[left +1]</FONT>,导致永远不会出现<FONT face="Times New Roman">x = a[middle]</FONT>的情形,算法最终在<FONT face="Times New Roman">x = a
</FONT>时结束循环,导致错误地返回<FONT face="Times New Roman">-1</FONT>。<o:p></o:p></P>  [% q4 z4 `* ^+ J3 Z. g5 A
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
/ P4 B2 m, V7 \- m* J' X<P >原因:循环结束条件错误,应改为<FONT face="Times New Roman">left &lt;= right</FONT>。每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改也不正确。<o:p></o:p></P>9 {& w5 \6 g* `& g2 [3 V
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
* Q( `# K6 k7 P4 A: M6 Z<P >除了有与算法<FONT face="Times New Roman">2</FONT>相同的错误,另外当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,必然进入死循环。<o:p></o:p></P>7 M) r; ~+ B: M0 r: Q
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>6 v4 H: H! A1 u8 N' `
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>/ [7 \/ y, i1 E! V
<P >如果在循环过程中出现<FONT face="Times New Roman">left = right – 1</FONT>情况,算法即进入死循环。例如<FONT face="Times New Roman"> x</FONT>≥a[n-2]条件成立时,即必然进入死循环。<o:p></o:p></P>
. W: R9 v+ j6 r( N' U<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>1 U& P& R, h5 q5 t8 W+ R0 Z
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>: @% y  C! \/ a
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
, _# t, q7 y5 H! x% j$ b/ z5 k<P >当<FONT face="Times New Roman">n</FONT>≥<FONT face="Times New Roman">2</FONT>时,在循环结束前有<FONT face="Times New Roman">x</FONT>≥a[0]且left &lt; right,<o:p></o:p></P>
  d) {6 T% g, {! H5 p* o<P >∴<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [left + (right –1) + 1 +1] / 2 </FONT>≥ (2left + 2) / 2 = left + 1,<o:p></o:p></P>
& I! X# I& F9 J5 t; Q<P >即:middle &gt; left成立。<o:p></o:p></P>
" `8 q2 @0 c! Q<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
  q* L! S1 H" X+ k* e7 R. Z# b<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>% C* f, i; Q- C! f0 q( v& a5 X- T% z
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
+ D: f& G3 j/ `  C7 q; \<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>& y0 _0 r3 f8 L  }9 I
<P >∴返回结果正确。<o:p></o:p></P>4 S. K5 u" R& C; _: o9 e! z; B
<P >(6)算法6是错误的。<o:p></o:p></P>
- J1 h# h# N+ U8 I1 ]) }; }<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
( P) a: W0 U) M2 l) p5 B<P >left = middle + 1;<o:p></o:p></P>$ j. p0 i3 W1 O" h+ B
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>: g0 R$ [1 \' a( Z' x
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
3 ]5 p0 R7 g+ z2 i<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>% l% T* u" |3 o, O/ v
<P >(7)算法7是错误的。<o:p></o:p></P>6 L2 w+ p. {, n5 v
<P >在循环过程中,一旦出现<o:p></o:p></P>7 P" r5 S3 ~  h. v/ T
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>1 v7 Q: ^7 i6 i" @3 a0 d/ n
<P >原因:right值的修改不正确。<o:p></o:p></P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-7-21 05:12 , Processed in 0.339591 second(s), 52 queries .

回顶部