QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2799|回复: 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) ~# f2 p6 `+ z  e< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
2 A( j7 _6 I  ^* k$ V< ><FONT face="Times New Roman">{</FONT></P>( c1 |1 y. Z+ E5 u7 V' c
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>  p! f& J) U/ C  ?8 U. J6 n
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>+ o: M9 t( t" N; C! R9 l
< ><FONT face="Times New Roman">{</FONT></P>0 _& y- l- R/ e$ i
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>8 k$ O! `9 F+ N3 G5 [9 P
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
$ {. s7 e- O* K7 ~< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
0 |6 ?. c* Y" t( v! `& |# m< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
- a: G& J$ u! l! `2 p; K, m< ><FONT face="Times New Roman">}//while</FONT></P>
& G  F( K- l8 D" t% C# ^- V& p8 R! C" t< ><FONT face="Times New Roman">return –1;</FONT></P>1 W; s. r- a3 r2 P' d) O0 u/ V* g
< ><FONT face="Times New Roman">}</FONT></P>. Y6 G6 `- r# K; `5 @- O/ r
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 r) H+ q- y2 {1 F! ^< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
$ M. P4 Q" P- l+ w) Z< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>" H" ~' g* B! Q2 T3 F% k
< ><FONT face="Times New Roman">{</FONT></P>
- G$ \  |0 _+ i5 ]< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>  \5 `# r3 o: D) y8 Z- [7 M9 e. F+ _
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
5 e5 ^6 ]$ O' e' E7 o4 M, F< ><FONT face="Times New Roman">{</FONT></P>7 a' e/ z$ P( K9 H
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
/ z3 p& r. Z! |" g+ B  g4 ]# m< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
( V: N5 V8 s# C0 m$ P; L4 o' o6 }< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
- Q* _' f3 n' F/ h) M1 Z8 B< ><FONT face="Times New Roman">}//while</FONT></P>/ m/ ]# l5 q* M: r
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>4 n: k& z+ u" k+ K0 @
< ><FONT face="Times New Roman">else return –1;</FONT></P>  H+ ]: P0 G  v6 P; d# R! ~
< ><FONT face="Times New Roman">}</FONT></P>6 e" ]: k9 N, A, u  l
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
& W" g: @- ]. \! L+ R& g! m5 Z6 |2 e2 v< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 T% B7 ]3 p+ f/ a< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>! J  Q" q' t2 N% I( Z
<P ><FONT face="Times New Roman">{</FONT></P>; ~9 ~/ W' l: n8 _, v, p' X2 h6 S
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>9 x/ n! _5 \- {1 \8 {1 Q
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
6 E( P9 L/ |" C. [! G- b! p! ~<P ><FONT face="Times New Roman">{</FONT></P>
$ x& A/ o  T+ ~<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
4 K. O; t# M# R; ~% H2 B. [/ h! q<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
' \1 G+ {, L5 z" f/ t<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>( e' d' T0 O' t& H. T4 k" ~
<P ><FONT face="Times New Roman">}//while</FONT></P>
* u, ~9 B- d6 n3 A7 ]6 n( G<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>$ v. A; V; R# [. B! i( h
<P ><FONT face="Times New Roman">else return –1;</FONT></P>- K7 d8 A9 Q: U7 T9 f! V
<P ><FONT face="Times New Roman">}</FONT></P>  {$ \2 B& f: i6 }. a& ^: R
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 ]% H3 T1 U. K( D2 s. x7 Y6 X3 _<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>6 q; M8 F/ |9 p
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
# r( A0 h+ t, e$ {7 }<P ><FONT face="Times New Roman">{</FONT></P>( s- n! _) }( O9 y& L* T
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>) x5 T! G0 g- I3 A9 E
<P ><FONT face="Times New Roman">              {</FONT></P>- G# F4 ~, C8 I/ h
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>) {5 x8 u/ [/ [, k/ F
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
) j! i6 @8 V+ J& X$ X; e<P ><FONT face="Times New Roman">              {</FONT></P>
/ a! \# ~$ J) x' U3 o- l$ E<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>6 V( A0 z/ ?1 u' G" P( P" w$ X' x
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
! h& R- }$ a: b7 s; H4 L, @<P ><FONT face="Times New Roman">else left = middle;</FONT></P>1 u- ~3 ^6 [1 C. Z4 C$ F
<P ><FONT face="Times New Roman">}//while</FONT></P>
2 A' C5 [  e' V% m% d9 u<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>! n) i8 E- r2 m
<P ><FONT face="Times New Roman">}//if</FONT></P>8 P( u, F+ `* N& G0 l. {0 {( Y+ J
<P ><FONT face="Times New Roman">return –1;</FONT></P>, f  }" C; |( ]6 }" @2 c. T1 ?/ z
<P ><FONT face="Times New Roman">}</FONT></P>$ g3 L$ C+ _3 w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
# z  _- Y' c; K<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ @2 y& X) o. A, z8 U<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
' t5 @8 \* _2 e! ?<P ><FONT face="Times New Roman">{</FONT></P>
- u5 ?3 P: X/ f# M( `; [3 b<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>, f- S% Z  x+ b! d) ~& ^
<P ><FONT face="Times New Roman">              {</FONT></P>8 ~0 o- i+ z8 o& {4 f/ M( u
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
9 o8 H% j/ r  E<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
" K! j, z6 n% m- J<P ><FONT face="Times New Roman">              {</FONT></P>" l5 d. g" U. W8 g- l
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
& D3 ~; G9 @9 l* N<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
. i. g& c! `9 z2 {& G6 n- c<P ><FONT face="Times New Roman">else left = middle;</FONT></P>/ \3 `3 w' |6 N  ~* N: B
<P ><FONT face="Times New Roman">}//while</FONT></P>2 c& E- i0 n! N  T$ Z
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>8 u9 p1 R, \# H' j% s3 r
<P ><FONT face="Times New Roman">}//if</FONT></P>3 J7 O7 R  u# ?/ ~+ e  ]3 v, P
<P ><FONT face="Times New Roman">return –1;</FONT></P>9 B, n" z+ n! j+ S7 Z) }
<P ><FONT face="Times New Roman">}</FONT></P>3 U# s! r$ n+ Q6 u5 q3 p
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  F- s, f) ]7 q) ?6 J* t<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>& `5 A# P9 |! U6 s
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
* d+ \$ B" d* D. e6 h4 G& }<P ><FONT face="Times New Roman">{</FONT></P>
% D0 w% H- G9 O, z1 Y; q* o* I<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P># P8 h6 g( S0 ?: `# K: o
<P ><FONT face="Times New Roman">              {</FONT></P>
6 @, \3 l: W! u4 m- t2 Y) J<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
) C6 n3 K+ z, W4 j4 `9 j<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>. C% C0 M1 Y' h- P# C
<P ><FONT face="Times New Roman">              {</FONT></P>
  K, I9 I3 C! c6 V( n7 _& M, g<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>& a$ X6 U2 {- P2 y8 Q
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
0 o" z2 X+ ?' x! Q4 f( z<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>+ Y6 x: s1 d0 O! X" k' V' J7 ~/ u
<P ><FONT face="Times New Roman">}//while</FONT></P>8 m# A& Q8 f) t6 f- H- r' s
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>* |6 F& O9 C; W
<P ><FONT face="Times New Roman">}//if</FONT></P>
! t  h0 A7 q. K' y6 h<P ><FONT face="Times New Roman">return –1;</FONT></P>
4 N- ]( e* |& L- n8 K1 y<P ><FONT face="Times New Roman">}</FONT></P>0 R, }: k5 w/ |& U3 |! T
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ S/ w; t; g( u* S$ S<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
9 q' ?! _1 U; w, f<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>5 I$ t2 l- I2 s  Z
<P ><FONT face="Times New Roman">{</FONT></P>
3 R7 W- k; {0 D% [! I. B<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
( J+ Y& @. {1 _' V& F6 t" T<P ><FONT face="Times New Roman">              {</FONT></P>+ l! t& @* o, ]/ }% ^8 R
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
( T6 a3 a* `  |/ `, X<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>/ Z+ e- {4 {2 _8 ]6 v3 T
<P ><FONT face="Times New Roman">              {</FONT></P>
. k( q& [# S- J4 I<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
  F9 o6 V* S+ {6 }<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>* q3 R% D3 H& d! m, w4 j: d
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
/ y& _( M5 h/ J  l- K<P ><FONT face="Times New Roman">}//while</FONT></P>
$ N( ]) t. m% i" j<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
$ _3 b: |" |+ v' B. @* O" t<P ><FONT face="Times New Roman">}//if</FONT></P>' H9 I# q' C8 ~- ]
<P ><FONT face="Times New Roman">return –1;</FONT></P>6 z3 Q$ b- ~7 G  W+ V/ @9 d
<P ><FONT face="Times New Roman">}</FONT></P>
- p6 H( c# r, i1 }2 A4 a0 [<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>$ t7 A3 D/ R( l# ?
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
- U! J$ k4 d' w" y8 R<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
2 h; `! m! }) n" Z+ w<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
* V! m' _/ P/ U3 i<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
; v7 i5 `; q2 w0 w$ d<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
  ~+ E0 t$ c3 ]  @6 E2 h: J7 G" P<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
' y1 s' m& R  u3 M- H1 Z9 v. Z<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>
6 f8 Z! L$ |, h9 X% G1 T& ?, |<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>8 T. z( A* S+ u) W, v
<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>
4 J8 a2 p0 y* k" v<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
4 K) }8 m4 _0 b* R* _* Q5 I9 [- ?<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>, ^8 j8 M3 w/ P: K
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>8 s' \0 U) Y2 H: c+ c
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
& v% y7 M3 C3 @* Y& V2 b1 X" T6 A9 S2 }<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>  O- J& `* G- H
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>- A0 I; N0 T8 G8 A' Q* g4 I1 @% n9 j; y$ ?
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>+ \" o7 x# t2 ^5 v
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>% c! @/ \/ J: s) c& s" P2 ?. S
<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>' K2 i5 |$ U3 C* c
<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>
3 [7 W9 {) {& B! W) L3 p  ^<P >即:middle &gt; left成立。<o:p></o:p></P>; ]7 |# L- O5 k& j0 s8 e( d: E( 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>
; N3 q& U5 L" [5 A8 N# Q<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
' e, p- a" Z) `# {<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
) B0 `( t! j9 X/ Z% `<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
6 _. s/ w3 g7 ?2 i# x+ V<P >∴返回结果正确。<o:p></o:p></P>
0 c; W) p& P% k1 P' R( d<P >(6)算法6是错误的。<o:p></o:p></P>. M/ x) x; ^  v
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>2 M- V1 [( ^0 W8 d) q3 K
<P >left = middle + 1;<o:p></o:p></P>
7 Z) l0 @; e: q3 z. d<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>8 P$ t) N' S$ y8 W8 m+ d7 ~. J
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>, A6 K1 Z* [3 I  I) y/ Z) t. k$ z0 K8 y
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
4 z6 L: ^- [1 [2 Q0 y& S7 F6 a; m<P >(7)算法7是错误的。<o:p></o:p></P>- w1 J; J! u: z. c/ \( i
<P >在循环过程中,一旦出现<o:p></o:p></P>
6 [% a4 k- z! A0 l<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
% L$ r- N7 O" a! [<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-4-21 07:48 , Processed in 0.447357 second(s), 52 queries .

回顶部