数学建模社区-数学中国

标题: [讨论]一道分治法的题目,仅供参考 [打印本页]

作者: lllaaa    时间: 2005-9-29 19:02
标题: [讨论]一道分治法的题目,仅供参考
< ><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>' k0 I( m: B1 Y& ?$ c( T
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
" F+ k8 ~4 l7 u* K# [< ><FONT face="Times New Roman">{</FONT></P>' J+ a& |4 d% ~9 z
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>& _' \! c9 v0 ]0 j4 f
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
4 T( l! Z; n% h( z" S< ><FONT face="Times New Roman">{</FONT></P>
: c- \8 C; d, n$ O' l< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
' R: n! K7 W& a$ \( }9 U8 n< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>, V; d+ v1 R2 n
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
: C8 y+ }8 m0 \' E< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
4 y% R6 k, P: f( i< ><FONT face="Times New Roman">}//while</FONT></P>
# H, B# U- P# o) {: ?" ^% \; n< ><FONT face="Times New Roman">return –1;</FONT></P>) p* h6 T$ q; M5 U
< ><FONT face="Times New Roman">}</FONT></P># B0 t( v! Q5 v4 s( Y* u
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 s; k3 L  I& ~& b7 ^< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>" c4 a" l0 r' A- P& U) F! x
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>2 [3 @1 Q$ N5 `( u4 {
< ><FONT face="Times New Roman">{</FONT></P>
* H- w7 l1 ^* r3 g& L; ~+ F< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>! r$ H6 a* l/ o" ?3 j
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
1 _# y( w# w# |2 M< ><FONT face="Times New Roman">{</FONT></P>
6 A6 F+ M1 J( z7 R< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>0 F! Q$ p+ [: C) K% q: H
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
; s$ @% ^5 b6 ^; r9 U< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
8 F! i) j9 h$ o6 y1 ~; |< ><FONT face="Times New Roman">}//while</FONT></P>
, O9 A( e  ]5 Y1 S5 h% i6 j< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
+ {/ w; c% F6 q" F, p3 x6 C" A< ><FONT face="Times New Roman">else return –1;</FONT></P>: d# D3 i& J' s% S4 j! t
< ><FONT face="Times New Roman">}</FONT></P>; _! w6 P% _/ Y1 B9 [
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P># i3 O  Q8 Y# j) U5 U! R
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. T1 x7 Q0 k* f; X< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
4 L! H7 ]& Y0 g<P ><FONT face="Times New Roman">{</FONT></P>5 e  I) u) V1 t' w' C  T
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 F" X- }, A2 m8 W% ~- c1 r<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
: n. c  _$ h! D: B5 c0 f<P ><FONT face="Times New Roman">{</FONT></P>+ R3 X2 X" R7 J: f$ K8 ?
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>, q& E+ ]; e1 T3 k+ q' E5 ^7 G2 p: \
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
% H0 n; i1 y; Y/ P4 `<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>; N+ s; W$ Z  y* t
<P ><FONT face="Times New Roman">}//while</FONT></P>( B( M8 }7 E% ?6 B  g
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>) m2 n" W6 P# T! z, ~# C" S
<P ><FONT face="Times New Roman">else return –1;</FONT></P>4 g! H5 J' \9 k) q" H) J
<P ><FONT face="Times New Roman">}</FONT></P>
1 k0 s2 L0 m! t& ?: f" R<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, ~) t* c6 C3 Q. O; i7 T<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
& K* |) W0 v! d# _/ W<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>4 L* `! O: a' J; A) w. x7 t
<P ><FONT face="Times New Roman">{</FONT></P>% _" u2 ~* O2 g& h) S' F) L
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
, Y. w, B2 {$ T4 s  H) D4 Z) P<P ><FONT face="Times New Roman">              {</FONT></P>
# y$ W! @0 h4 j2 {. \5 i9 h9 m<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>' e% }7 e3 w1 m5 A* q
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>' Z6 I  S, r: S! H
<P ><FONT face="Times New Roman">              {</FONT></P>/ Z' e, c" j- }9 `
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
+ k/ c9 |* H% u6 `) G- S<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>4 h4 x% a4 U+ \; b  S
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>* ~; h3 K' j" b8 v6 ]2 F0 E" {) T
<P ><FONT face="Times New Roman">}//while</FONT></P>6 @( R, J- z& [( i  n
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>4 Q  c  i* {$ e  _( W" G" K. c* W% \
<P ><FONT face="Times New Roman">}//if</FONT></P>8 X) C0 A) h7 e; l. H3 u5 z
<P ><FONT face="Times New Roman">return –1;</FONT></P>! ~7 D! \# E( `) L
<P ><FONT face="Times New Roman">}</FONT></P>; H$ U6 f6 K& b
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
1 q' o* b' ~( m1 A. b* X# N: f% x$ v: X7 j<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% T' A/ M) a4 Z, s3 d" e# C& `: r4 t<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
- R+ l7 e% q5 k" m5 |: [<P ><FONT face="Times New Roman">{</FONT></P>
2 W: Z9 u" D7 Z8 y" \# Q<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
1 K% G6 E9 x  f: R! A2 @5 r<P ><FONT face="Times New Roman">              {</FONT></P>
7 [+ ]1 w8 Y. H. x; e3 h' v1 m<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
1 C+ d- _) J( X6 \: d5 [2 B/ a: q<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>5 L0 V! A3 W5 Q+ d* ^% d
<P ><FONT face="Times New Roman">              {</FONT></P>
, \0 D/ L0 I! m$ B$ j9 {$ @<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>2 N. Y. R$ q8 o7 P
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>+ Q% v$ B) e0 b& O- ]
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
7 R, H1 p: E$ [5 k8 m5 j<P ><FONT face="Times New Roman">}//while</FONT></P>
9 h; P6 c! i8 @6 a<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
  X3 L8 F' z+ E4 g- h7 K<P ><FONT face="Times New Roman">}//if</FONT></P>1 S$ l, X3 `: K8 y# D
<P ><FONT face="Times New Roman">return –1;</FONT></P>
; T5 x, T8 i0 J6 b- R# r2 f7 p<P ><FONT face="Times New Roman">}</FONT></P>
( [) u) q! f2 |3 ]8 S8 v* N<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 Y& R  |2 `3 F' m
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* L, r$ t  S7 \1 t( N* @<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
5 ^2 y/ Z7 M) y  H<P ><FONT face="Times New Roman">{</FONT></P># v% V$ D1 J3 U( I  m
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>2 b5 H# ^/ i  G
<P ><FONT face="Times New Roman">              {</FONT></P>3 P2 ]' C5 w- l" L& b
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
* B0 y7 I, a# ?# \/ o8 Q4 \$ r<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
, j# I" k+ P7 J9 }# |<P ><FONT face="Times New Roman">              {</FONT></P>
/ Z2 G8 J! w9 J; o1 D6 l- N  e<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>) |7 s: S2 ]# T% L# D! G  S
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
* ^1 ?9 M" o$ s' G3 B1 p/ I<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
% j" j: i4 i4 A0 r4 R* I<P ><FONT face="Times New Roman">}//while</FONT></P>
, w2 v" I% }2 G9 w# c5 p$ ^3 s; m% R% I<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>5 J6 g5 N' ?& k+ s  W$ F
<P ><FONT face="Times New Roman">}//if</FONT></P>
* U: P9 P8 d) x# |) k2 G: f1 S! T<P ><FONT face="Times New Roman">return –1;</FONT></P>
2 @" X$ q3 c1 g<P ><FONT face="Times New Roman">}</FONT></P>
( R4 g. U7 y# f, @* {1 B% r<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) b# V: n2 H* z9 ~, A4 \! |
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 l/ [+ O  |- d- H
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>0 F: x, _! Q- E- R
<P ><FONT face="Times New Roman">{</FONT></P>
' h* A0 S, E! k) f, h<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
- u% X) y% r0 r1 y+ w( R/ _<P ><FONT face="Times New Roman">              {</FONT></P>
9 ~' U# L, b1 n: d; b% V9 l2 i<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
% t, u  z2 ]3 b/ ^<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
  O- ^$ t: i$ L- i+ C  `<P ><FONT face="Times New Roman">              {</FONT></P>1 P" z/ R2 M/ N4 f: r; W$ Z+ }
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>. I6 n, C' U9 {: W, X
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>8 F" P3 C, i9 x# F! O5 A: ^
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>3 q: h$ [& G1 d1 ^5 a
<P ><FONT face="Times New Roman">}//while</FONT></P>
% M- h9 @7 w( P7 ?8 J<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
/ o$ q* |0 [7 t/ w8 O0 |3 v<P ><FONT face="Times New Roman">}//if</FONT></P>
: C! k& g. m' Q  R<P ><FONT face="Times New Roman">return –1;</FONT></P>
/ @1 H8 j" Y+ g7 ?' x+ D<P ><FONT face="Times New Roman">}</FONT></P>
$ G) @& r6 z" i/ B<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' t# |( r# u) C: t/ |3 e
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
' [0 A( F% i, |6 j1 f8 ?8 A- z<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
& x% y! x6 m: i" T" d/ |<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>/ m$ \/ X7 Y: E/ s1 R3 f
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
# g+ z- R% j1 O. L: A0 C" O<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
1 i7 h2 a, B# u3 [1 k' a<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>: A, S2 r; d9 }; z) U, P2 ~: s7 ?
<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% @; C' q- u7 S& X* y; l8 k
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
6 U9 D: T" g3 r* @! i% U% c5 H& E<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>1 E4 W3 t7 X1 z# L7 H6 ^, v3 I
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>$ ], V% g9 K3 Y' |1 d: P
<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>
6 C+ ?5 b2 S2 i3 w, s<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
8 [% [1 [. W% A- P6 ?<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>( p/ b# g/ O7 u7 K/ v( j. C" P6 S
<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>
$ i' s4 F3 a' R0 M! f% a( d<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>, }9 ~! M+ Q; E# I; g& h
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>' D% V7 a4 a8 q2 C0 d4 Q/ D1 _
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>1 b3 u) M* U$ |: J
<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>4 Y/ D. t( f- _6 A
<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>
1 e+ k0 y* p7 M: N) T) E. g  r/ o<P >即:middle &gt; left成立。<o:p></o:p></P>6 N( d3 ^& w2 k9 d9 y7 X# |9 v
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>7 [- Z+ f" j& s/ |* n
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>9 o0 J; H, g$ a9 a& T. O8 Q
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
# B- _, {) \* J/ W) e( Y  G8 }1 k<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>" ]$ v: @$ H* ?- Y4 r! H) B
<P >∴返回结果正确。<o:p></o:p></P>
6 E1 X+ w- r. t0 P# [% r<P >(6)算法6是错误的。<o:p></o:p></P>! O* b* o  S7 ~/ P8 y
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>1 H; `, w+ S5 f7 [; c
<P >left = middle + 1;<o:p></o:p></P>
! y! ~) m5 ~. h: u# m) B8 O' t<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>7 O/ z4 U5 X! G8 s
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>* s2 d) V% C3 a' k2 T- u
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
, ?1 d& {0 n: {5 D<P >(7)算法7是错误的。<o:p></o:p></P>  m0 w. `) n% t6 Z' }+ q
<P >在循环过程中,一旦出现<o:p></o:p></P>$ d3 ?4 R) I: ]
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>7 j- K0 ]2 ?4 L# Z, P/ y: C
<P >原因:right值的修改不正确。<o:p></o:p></P>




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5