QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2909|回复: 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>
- f7 D. j% \2 @3 z< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>* w! L7 p8 `5 [  q
< ><FONT face="Times New Roman">{</FONT></P>
. b' a0 f) e- y$ V4 j4 u% L< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>/ _$ V$ S( J! }$ e  ^2 {
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>" q7 ?5 N0 ?! {" \
< ><FONT face="Times New Roman">{</FONT></P>% ~: Y7 }' T! B) o( }6 ~" r3 ^
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>- o% q- V( p. R6 W7 W3 y
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>( z9 ]' R5 r# A
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>- E) B6 |0 Y/ I' U8 K
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>$ `2 n3 s: ]$ D! D; W! ?- R+ ]) m. j
< ><FONT face="Times New Roman">}//while</FONT></P>9 |1 i. L& O" Z1 f) w) o) h( n
< ><FONT face="Times New Roman">return –1;</FONT></P>
1 X; s5 R( }& E5 V- i< ><FONT face="Times New Roman">}</FONT></P>
2 I$ f1 Q9 V/ L3 F< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ E8 @1 _9 g. C, G6 n3 {% U
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. e- K% S& f  B< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
! Q% g0 I7 B( X  n: B0 p7 ]< ><FONT face="Times New Roman">{</FONT></P>
" W: l( |( E5 {( v9 @< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
; e. u$ S* G4 u9 S8 q: }5 S/ k. g< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
( w5 C- V1 v4 `! w" r2 G< ><FONT face="Times New Roman">{</FONT></P>4 A1 \: h% w, q0 _3 D. c
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>4 u+ ]# f# X* _0 U5 @+ l7 [9 q
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>9 _6 T9 @2 K+ B4 |  d/ \
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>7 b8 H9 n' P$ ^/ x% V
< ><FONT face="Times New Roman">}//while</FONT></P>5 `! }0 V; @" t9 Y% L
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
, e- Q$ l3 X' l< ><FONT face="Times New Roman">else return –1;</FONT></P># Y( n& ~+ Y# o4 i8 ]0 U6 B
< ><FONT face="Times New Roman">}</FONT></P>
: J3 t" |- U5 E. N* z& A< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>1 l/ _# s2 A1 h
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P># c6 D5 r# Y6 Y( X% H+ D- R1 @8 b/ n
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
$ Y; B: _. g/ S  n  I, k<P ><FONT face="Times New Roman">{</FONT></P>4 Q4 h3 m, N9 G
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
& L, `0 G* x# E% S<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>* _2 F8 _" ?7 x
<P ><FONT face="Times New Roman">{</FONT></P>1 V8 M. W5 H) _$ W. U+ C, c
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>. @9 p; s1 W; X. _* W% a
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P># ~( f6 X1 }& ]$ f0 |/ K
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>8 J4 f$ J# W0 H6 y0 L$ S
<P ><FONT face="Times New Roman">}//while</FONT></P>
" d7 }4 q$ M2 m6 N" L& M  q% N: P& r<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>3 ]% v4 G0 S5 N+ S* U8 c- N  Z
<P ><FONT face="Times New Roman">else return –1;</FONT></P>
- ~! f( P7 j8 o( s<P ><FONT face="Times New Roman">}</FONT></P>9 r' {' c" h* K& \
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: T( P/ A% }( D& _, K. y<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ u/ c; C6 d5 m6 o. S- R% y5 F<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
2 x" P( w9 c( d- x* E# B<P ><FONT face="Times New Roman">{</FONT></P>; x1 B- O8 |4 o& T, G  v& N
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>* l5 I# \4 }- X! i$ g6 h% Q' U- \/ [7 c
<P ><FONT face="Times New Roman">              {</FONT></P>6 [# i6 }" r; p# R1 S5 m& F5 t
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
! N8 e$ V# y. E7 _% C8 z<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>( ^( a2 g2 _& @/ a. y4 d
<P ><FONT face="Times New Roman">              {</FONT></P>5 c! Y# S; \" d& C' U, M
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
) K7 ]- [9 ]& p+ k4 j. ^; V7 C<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
3 a' m0 a8 C3 i4 h/ h<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
5 R# x. Y, x6 X<P ><FONT face="Times New Roman">}//while</FONT></P>
( y4 t$ m3 F* h; b<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>" B* K8 @/ _6 r3 A- |* E2 g+ a  Y
<P ><FONT face="Times New Roman">}//if</FONT></P>
6 M  L/ ]7 o2 X4 f) j# j2 }<P ><FONT face="Times New Roman">return –1;</FONT></P>
' u  s+ ]- ^0 `. k<P ><FONT face="Times New Roman">}</FONT></P>0 k, {# A( v4 [
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
( F4 F& ?( O# o  k6 v<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 l4 A) _0 N" m2 L8 e<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
; n) i( D: c! V0 _. E! J! J; d<P ><FONT face="Times New Roman">{</FONT></P>
, X: K4 y: a& b5 b( l% j8 [/ p<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
: x% b2 E$ n" P" y<P ><FONT face="Times New Roman">              {</FONT></P>6 F* F. ?# ~8 x, z
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>! ~8 v% d  {- }7 a4 E# j  ?% @
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
- t: _) F+ p8 }* W<P ><FONT face="Times New Roman">              {</FONT></P>
$ |/ _4 B" C3 e5 H5 w* J( G1 X<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>, s) B- j4 y$ V# z
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>; A/ W5 W/ s% ~$ ?0 }5 i* }5 t
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
+ D0 f2 b+ R5 m/ Q* l<P ><FONT face="Times New Roman">}//while</FONT></P>
$ f! n" S* [6 p( ?5 y  P7 ^<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
9 }, T+ Y3 U0 P3 x. B( f<P ><FONT face="Times New Roman">}//if</FONT></P>
- K. @% `  P( |. A<P ><FONT face="Times New Roman">return –1;</FONT></P>
  M  Q$ Q$ h) {  z( X<P ><FONT face="Times New Roman">}</FONT></P>! g, O# K' `  V2 n2 M3 j
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>. _+ [: w( X" z1 y: }  y
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
2 {; j. ^' _' i+ B' S. t) c& ^2 v<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
+ N6 b1 h2 k( V( o* w  P4 u# B<P ><FONT face="Times New Roman">{</FONT></P>
$ Q5 D4 r/ Z2 ?% [<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>/ W) I# e, C3 @2 {
<P ><FONT face="Times New Roman">              {</FONT></P>
9 c) {. n0 @  C6 A<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>+ u# l! Y5 q& m8 ]) f: ~" O
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>8 a$ W5 x; r. u2 Q+ G$ A
<P ><FONT face="Times New Roman">              {</FONT></P>
" M, Y( s, F, E' p. m: ?( e# Z<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>( c/ q5 B! j0 ~1 b2 w/ ]8 o! l
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
! q( w/ j* J& C3 D8 O- a* k& w$ d<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>. Y. e1 o9 s6 o+ [5 v2 y
<P ><FONT face="Times New Roman">}//while</FONT></P>
' K8 V  O0 q. I( q' x6 t  ]& i, \<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>2 d2 P; E6 A  b: O
<P ><FONT face="Times New Roman">}//if</FONT></P>4 m" G3 e3 E4 V& V
<P ><FONT face="Times New Roman">return –1;</FONT></P>  v. Q$ y4 _% u7 N2 X
<P ><FONT face="Times New Roman">}</FONT></P>& E6 @$ F3 E- B3 F3 L  o
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 ?0 b. n9 ^( J
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* Q4 F/ b. y6 b$ w<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>* c: H. {- {1 W2 H& t. P
<P ><FONT face="Times New Roman">{</FONT></P>& B3 M5 v1 |' Y" E+ h& m
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
7 U* C$ s' P5 i) p% v9 x<P ><FONT face="Times New Roman">              {</FONT></P>" |. r' P0 D& k1 E
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
1 j  [( S% s* Y0 F<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>; A4 \& u9 P1 B. Q2 l" Q
<P ><FONT face="Times New Roman">              {</FONT></P>. S1 O) ~' s* Q: |7 C
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>0 L% {: S* H) g8 r; p  t: \$ `
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
  D" N3 {& i( J! L7 r6 ^<P ><FONT face="Times New Roman">else left = middle;</FONT></P>5 t. q0 F4 G% Q9 F' ~8 j
<P ><FONT face="Times New Roman">}//while</FONT></P>& {( d0 j4 Z1 j0 E2 A. ~
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>" ?5 T' z. @; r: O8 F
<P ><FONT face="Times New Roman">}//if</FONT></P>
, q5 C" K4 s# {9 d& q0 W3 Q<P ><FONT face="Times New Roman">return –1;</FONT></P>) @% U2 v9 M$ p. p/ \2 A5 j" k
<P ><FONT face="Times New Roman">}</FONT></P>
5 z9 C: C, B7 r0 w3 u* x<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>9 l( ~; G0 }8 v6 \" ?/ e+ u- m
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
3 B; o1 n' a) E; S' b$ o& P$ g$ |<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>! a% I5 e" }; N! p5 @& R) q6 \
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>3 }. i/ Q/ d) K0 k- g4 L
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
5 I8 L4 D7 A4 A& ]* `<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>" Y% z" v+ e6 E& A4 G9 {
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P># J. a" _8 y- \0 @, t; X' f2 G
<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>" A$ P9 {: L  f1 Z& B
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
: `. n9 u+ w8 s# n6 b) _<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>/ z0 P) M' M! ]" X
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
) s* f: ]9 w9 g2 G<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>4 z+ F- L. A! Y2 D1 q, l. }
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>4 Z0 K: p$ J& H( c& n* B, l3 j
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>4 N/ d7 U! K& P# ]! [7 N) X
<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>8 X5 g0 Q* M7 K/ x
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
; ^0 V( J. _, p5 m) x& _<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>, f; L: o2 x6 Q: P! n7 T- w
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
( U( |/ H2 U/ k9 {<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>
! C9 h" H0 W% L. ^5 J" [<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># T5 H2 y. D8 n9 c) Y4 f8 R
<P >即:middle &gt; left成立。<o:p></o:p></P>
, P3 O/ d5 C1 o0 r# y<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>4 Z3 X0 e6 r' r
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>* T1 |! O6 Z* |& h( [
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>0 v" h( H5 n3 ]5 v9 U
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>0 W  |, S) e3 j
<P >∴返回结果正确。<o:p></o:p></P>
2 G$ T9 T; q. j- O<P >(6)算法6是错误的。<o:p></o:p></P>
# ]9 @) O7 y4 P& L<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
9 h" t9 p8 o/ P! ~3 Z9 t<P >left = middle + 1;<o:p></o:p></P>
) W6 ~9 e; B+ A0 Z<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>2 W2 |/ O- y% V/ h4 h, L+ j: H
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>& p: t1 S  A8 c) D4 d
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
' [! W% s/ k6 P* H5 x; A<P >(7)算法7是错误的。<o:p></o:p></P>
: I* y( t8 j3 @2 k+ J<P >在循环过程中,一旦出现<o:p></o:p></P>- v9 o0 H* x1 o; ], j# B
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>7 F. |7 o1 r$ N3 z+ R+ a5 D1 K2 e
<P >原因:right值的修改不正确。<o:p></o:p></P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

fastpost qq
收缩
  • 电话咨询

  • 04714969085

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

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

蒙公网安备 15010502000194号

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

GMT+8, 2026-11-1 11:57 , Processed in 0.249926 second(s), 51 queries .

回顶部