数学建模社区-数学中国

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

作者: 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>5 ~$ ^$ @) F5 T- t& G5 `9 @" J
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>9 F7 O  S$ n# b  A
< ><FONT face="Times New Roman">{</FONT></P>
% ~3 o5 |3 W" A9 p, q< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>4 y) k2 a; l/ `3 I4 m5 D% n
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
% m6 X( @2 ]0 k9 O) h( m< ><FONT face="Times New Roman">{</FONT></P>
2 f+ B1 e' [! T; |* R% l. |6 J< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
0 n- ]( O) v8 j< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
2 f9 W1 i2 b+ p< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
- k# B3 F. F& [4 _" R6 G) U< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
" M+ |% F  b5 b7 c, T1 \< ><FONT face="Times New Roman">}//while</FONT></P>
, [4 a- p$ z$ O0 j< ><FONT face="Times New Roman">return –1;</FONT></P>
7 ~/ x) x' }% }( r8 H6 [< ><FONT face="Times New Roman">}</FONT></P>
2 h, v7 C( P8 K( ~+ ^< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  d4 `# m9 c- c; a9 _+ _/ ^
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  C" J  d5 Z" m
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>5 Q0 f2 J. P% z. O- I" s
< ><FONT face="Times New Roman">{</FONT></P>
5 d# l1 _) w6 M< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>: [* u, g" X, C* X  F( Z2 R! I
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
9 D2 z% o  d- D, Z+ J, G1 Q< ><FONT face="Times New Roman">{</FONT></P>
8 y% X# u! S9 `< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>/ b% K$ _: g7 @/ O, T5 Z
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
- g0 H& u& v, [2 u" z, F7 B& H. ^, {1 z< ><FONT face="Times New Roman">   else left = middle;</FONT></P>% M. c4 h; |( r) ~% [
< ><FONT face="Times New Roman">}//while</FONT></P>6 D/ j, s1 q' I0 n0 O7 j
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P># I# a9 V: C& S0 v0 N/ c/ C8 f+ ^
< ><FONT face="Times New Roman">else return –1;</FONT></P>& F& k. f6 C* P6 Q# Q; o
< ><FONT face="Times New Roman">}</FONT></P>
+ e/ v4 W) W8 Y; g. [< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; r# F4 _! x0 F8 ?< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, k# [* R, D1 E) {% s< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
6 }6 }! E, q$ q. \<P ><FONT face="Times New Roman">{</FONT></P>& b+ e+ _8 v8 i7 e
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 `4 N5 u+ O  M<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
: k" r2 u& L$ t5 [5 U) H<P ><FONT face="Times New Roman">{</FONT></P>4 y% y+ M: l& v* k  V7 u% _7 v) y
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>' l4 q& ?& M. e' I$ t  |
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
6 {* i  Z# d. f  `* A/ {4 Z<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>3 c: S' z3 I1 e! K: F/ U0 w
<P ><FONT face="Times New Roman">}//while</FONT></P>
, Z5 a1 R: j. h  O<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>7 u7 Q) l7 p9 L# e6 Y, O" Q! R
<P ><FONT face="Times New Roman">else return –1;</FONT></P>: @) l& O) ?2 k; p: \1 d  P: P
<P ><FONT face="Times New Roman">}</FONT></P>
+ y0 K  d. F- H<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, O4 N. \9 N6 `<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( v  g" _. h! n% m9 O) E4 I
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
6 S7 A' j+ A, Q' |9 q<P ><FONT face="Times New Roman">{</FONT></P>2 m0 Y2 T: z: U
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>, Q! w' ^! G4 r$ F8 P, `
<P ><FONT face="Times New Roman">              {</FONT></P>/ R" U9 K& o* N) k
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>7 C$ g% W& Y' L- c& x/ o( _0 |
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
3 W5 [. t: V+ k) U, f. N<P ><FONT face="Times New Roman">              {</FONT></P>. g/ Y7 W! p$ X& T4 ^# l. W% Q
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
8 M" w+ E& A3 l4 s8 h<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>. e% C$ V2 _  Z8 P! v6 K( e
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
) s: k* a2 T3 T! u0 U<P ><FONT face="Times New Roman">}//while</FONT></P>
6 n  }" R4 u: J6 G! F<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
& q: }: r$ K7 I6 d<P ><FONT face="Times New Roman">}//if</FONT></P>6 q, w3 o6 O, M6 F; Z# \! N
<P ><FONT face="Times New Roman">return –1;</FONT></P>
! v4 i, I5 v) E& e9 a) y$ m/ G2 N' F<P ><FONT face="Times New Roman">}</FONT></P>
$ ^" @! ?0 z  H. D% \9 n3 w<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
# Y5 f1 Y, a! g2 g8 G5 N/ T4 M1 [<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 t( l; S& x3 S5 d  h# k& j
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>3 S' d' {2 J, |6 Z
<P ><FONT face="Times New Roman">{</FONT></P>& c# B( P# B2 t3 I! F% ~2 M
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
( L9 R. Y+ e" A% \! C<P ><FONT face="Times New Roman">              {</FONT></P>% o$ d8 h( P1 [
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>1 f5 |$ y, V% o& [2 [" A8 k
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
1 T$ A( j9 q+ Z<P ><FONT face="Times New Roman">              {</FONT></P>
( d) e( J8 Z% ^. p8 F<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
5 w. N3 j& R2 |<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
9 z# Z: c3 f3 z! k7 N<P ><FONT face="Times New Roman">else left = middle;</FONT></P>7 Q8 S, k' h( R" y2 C/ w1 ]
<P ><FONT face="Times New Roman">}//while</FONT></P>
! C# `& z& F8 n0 `+ @<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>' i9 H9 p; W4 H; t
<P ><FONT face="Times New Roman">}//if</FONT></P>
8 m3 m7 Z' s" f! s% [, \<P ><FONT face="Times New Roman">return –1;</FONT></P>$ m; A2 m, B  t, z8 O
<P ><FONT face="Times New Roman">}</FONT></P>
: u5 }, U% K% W# \2 y0 `7 o<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  W" I& A  w) [2 l<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 u' O0 k7 a% y7 k: J8 t2 G
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
. H8 Y8 M3 g8 d4 K( @<P ><FONT face="Times New Roman">{</FONT></P>
1 V/ Z4 ~+ o0 y/ P3 y$ h& u8 k<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
4 ^, O( B7 V/ t& E2 o7 G# E, Z<P ><FONT face="Times New Roman">              {</FONT></P>. ^9 w/ r. l/ Z' b0 @8 [) R
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
: ?! M! U2 J/ `# m' `+ y<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
& t1 x) O! e1 ~+ `7 Z  s3 F$ F<P ><FONT face="Times New Roman">              {</FONT></P>
+ k" Q9 Z! P4 p0 J( w' L<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
3 @3 i& W; L4 \! Q2 k+ O+ i<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
" c/ Y( U: _  e* f<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>5 l& a. c& Z* V" S# N. Z3 \
<P ><FONT face="Times New Roman">}//while</FONT></P>
7 ~3 r3 S1 T6 u* L. c% A, A<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
* ^( I+ T  ?: L1 d<P ><FONT face="Times New Roman">}//if</FONT></P>) C% k, J# J8 e: ?$ g; v# u
<P ><FONT face="Times New Roman">return –1;</FONT></P>
$ [! N! q1 m( |$ |2 |; T<P ><FONT face="Times New Roman">}</FONT></P>. L8 I( A7 {2 G
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* r/ m( t: F: A
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ t2 D7 L# u( }4 l/ E2 U
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>/ B8 J  H3 t; J% c# f
<P ><FONT face="Times New Roman">{</FONT></P>
9 L. h  c% Z1 H- a3 P6 z+ M: n( x4 ~<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>: G* a5 a' |! O5 I5 X* K7 s
<P ><FONT face="Times New Roman">              {</FONT></P>
0 h3 {+ \2 g3 A8 n<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
, K; r2 T3 T% ]' C/ u# X1 z2 H<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>, g7 p% m/ A5 \. B. T1 y
<P ><FONT face="Times New Roman">              {</FONT></P>$ E" L. a$ V! E
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>; u; m- p% {4 U! N7 u
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
( r& ]: p$ P) L0 y$ S<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
: v$ G8 \- A! W' I<P ><FONT face="Times New Roman">}//while</FONT></P>
; E% D& d. x# X2 r<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>8 ^0 ?6 r+ }6 E
<P ><FONT face="Times New Roman">}//if</FONT></P>
/ ?0 L1 L. o: R# K6 ?  [) f/ E<P ><FONT face="Times New Roman">return –1;</FONT></P>
. l& b; e5 w. L5 B% z<P ><FONT face="Times New Roman">}</FONT></P>
, D2 o% _# O9 ~; d: Z' |1 J<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>8 [) v2 q8 d& I3 Q6 J/ P! I$ m( N( I
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>: V" w/ ]2 D6 C9 i+ \
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>2 A' j4 O" u8 s# ]
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>' b8 K2 D+ n0 T; l0 z
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
; `+ Z% `4 |" R) F$ m* f: W  d2 b/ z9 |5 i<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>: [) O6 n# z; e' \5 p0 w2 P
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
* N, C. p5 A- 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>) l. U& O: m* ~( J4 _/ A" A
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
+ s0 W% p/ x/ K% e3 d<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>
, A2 {0 ?- D" i1 s9 g<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
* ^1 j' i- |5 n' X9 \7 U<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>
( n1 `  D+ z( i* H$ L<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>" F3 q1 s3 a' C$ P: v6 |
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
4 H2 o6 W* a- `- E" u<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>/ R2 Y) V& L- s1 l5 u5 i0 q
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
. e+ H* j6 f4 {5 Z$ [3 C<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>" \/ {; b' i  Y6 s$ t7 [
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>8 I/ T4 y7 v$ q# V; D
<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>
# |+ C* V9 L) j7 K$ x<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>
- e) L  K0 v# E& q+ U<P >即:middle &gt; left成立。<o:p></o:p></P>( _4 e+ p1 d* H: `% u" c
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>, j7 b' X; }8 T  Y8 _' K4 ^1 d- S  o7 @
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>9 K: L! z1 v' A# ~; \' E- l9 g# G
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
- b7 P; U7 x. U! Y: K8 O( b<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>- w: `( x& p0 B
<P >∴返回结果正确。<o:p></o:p></P>4 y# Z1 i3 J9 {0 \3 S
<P >(6)算法6是错误的。<o:p></o:p></P>5 C, p( w3 M4 _2 ~9 h
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>3 \  ^) m6 T7 ?, f' i
<P >left = middle + 1;<o:p></o:p></P>
$ O% M2 H) m- c  w# R# A<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>: }5 ?: ]8 f$ }( B9 j3 t9 g9 g
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
# j. J% |  ?/ j1 u: e<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>: @( O# e9 e* D! K7 p, c" Y
<P >(7)算法7是错误的。<o:p></o:p></P>* o. Z9 a9 i1 U, ^, i, l) U: _+ X, J
<P >在循环过程中,一旦出现<o:p></o:p></P>
9 O& k" W% s' @3 ^" |' [% l<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>  A' ]" w& Q* J6 y  H
<P >原因:right值的修改不正确。<o:p></o:p></P>




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