数学建模社区-数学中国

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

作者: 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>* C4 U3 [0 r7 ^4 N
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>8 b! @1 Q6 U% p* t  c3 y0 Z
< ><FONT face="Times New Roman">{</FONT></P>
4 K1 D( Z, N, c$ o< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>8 S! I5 C. n' K/ [; j
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>& W% h7 F- t3 W$ y3 M* ?0 Q
< ><FONT face="Times New Roman">{</FONT></P>$ e- ~& z0 s, Q$ h2 s0 W& P
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
# e2 I# u2 E! G5 M9 \  U< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
' V# c; m, X# ]% ^* D- e8 d) X5 Z3 W< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>* T7 w# U+ q: {# R# ^' K/ {
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>2 J0 t+ R0 m7 x, K, O
< ><FONT face="Times New Roman">}//while</FONT></P>
7 F. U5 F, C/ m  a9 \% o, S< ><FONT face="Times New Roman">return –1;</FONT></P>. D3 i4 U4 o; \
< ><FONT face="Times New Roman">}</FONT></P>
8 f1 ^( Y) [  u9 X< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 o# f8 ^, k) v( m) ^( x
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; A3 B" W! T4 Y! ?2 m< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
0 \0 n3 e" r- _8 r) X+ R< ><FONT face="Times New Roman">{</FONT></P>
& a1 d, y' x4 ?" }" f7 s% V< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
4 k! P- \9 k8 ?* w) B- S& J% f. q< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
' l- f, U& ]4 @' [" Y/ G6 o; P+ t< ><FONT face="Times New Roman">{</FONT></P>4 G( x7 N: t3 D1 Z% h  u
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
) j7 w4 I" x0 F7 q; V2 D< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>/ X- }& m6 }- {3 N9 N& t
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
& [- j5 [* E" n1 g: W< ><FONT face="Times New Roman">}//while</FONT></P>
) f6 C. ]$ [0 U, p/ P, Y% K< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
; A. Q# P1 u$ o* j3 Y< ><FONT face="Times New Roman">else return –1;</FONT></P>) C$ A- j1 [/ i  q8 Y
< ><FONT face="Times New Roman">}</FONT></P>
" j- w/ h: b) v8 [! y< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 b$ g% J* z- L5 H! g" Z3 {0 P$ `5 l" M< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>9 _+ ^& \& B$ X' r2 q3 n8 L
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>$ K# c# t5 l0 r1 r  ]2 G- Y
<P ><FONT face="Times New Roman">{</FONT></P>
9 N# s" y2 L! j6 F( A$ u9 ^<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>; V2 Z, D8 P6 L! n1 V" K$ ^
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>) ]& M$ t6 R& p7 t" T7 Y0 h
<P ><FONT face="Times New Roman">{</FONT></P>
- U1 N. K+ l/ `) G$ w<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
8 z4 i5 ]  r% G3 J$ [1 w<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>' n# K9 F5 ^. [0 M% k% _
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>* q' b" x+ |6 |- G/ \
<P ><FONT face="Times New Roman">}//while</FONT></P>9 x) q8 h) j/ u( f, _: d3 E4 L$ j2 e
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
$ `. ~3 s9 F/ O  W8 L<P ><FONT face="Times New Roman">else return –1;</FONT></P>" k! u0 }$ c1 C
<P ><FONT face="Times New Roman">}</FONT></P>
, W6 j! ^. w# `9 Z<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 K! a0 h7 p7 b# o' ?. p& m: n<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% {, D; e9 A# ~0 t<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
* R5 o, R% d# o<P ><FONT face="Times New Roman">{</FONT></P>7 |6 w$ F' }9 R, e9 |' j
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P># J( J$ a2 ^$ R3 N0 D/ ^9 k/ S$ F# }: n
<P ><FONT face="Times New Roman">              {</FONT></P>7 V4 Y+ A  k9 s
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
' e, F% ?, w6 v$ S6 c0 {+ @( Q' q9 D<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>+ }# O4 E' o/ a; n! e7 @
<P ><FONT face="Times New Roman">              {</FONT></P>$ I. Y) v  r1 g9 D- M
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
. u) i# c0 i* D, d' _<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>8 d: f: h. ?% M. Z) G( K* F
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>6 k! t  e  @+ Y" \5 ]* p* [' S1 }
<P ><FONT face="Times New Roman">}//while</FONT></P>- U( f# m7 ^# n' O+ u
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
. a: c# ~3 T$ f<P ><FONT face="Times New Roman">}//if</FONT></P>
: v( O" A8 f* i- \<P ><FONT face="Times New Roman">return –1;</FONT></P>
# O) u: i/ G  v" M<P ><FONT face="Times New Roman">}</FONT></P>, D8 t6 X7 d7 v+ w, z
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ ~' k9 }7 l7 z0 Z$ q<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
- n& v0 m$ i: z; B8 T6 l' E; R) p<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
- y" p# V9 H& c' J+ S. ]<P ><FONT face="Times New Roman">{</FONT></P>
3 j9 E# g" r9 J4 A! q- ?<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
, e, |7 I6 J* Z& C& X  N4 ~<P ><FONT face="Times New Roman">              {</FONT></P>
  I4 h2 X$ U  X, T! y<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>: q: x7 ]) Q- L4 B
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
4 u& @3 d; p4 H0 Y! n* f<P ><FONT face="Times New Roman">              {</FONT></P>+ U+ m+ \  c% s7 l" U( m* C, |5 ^
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>2 S1 a" n$ t: ]
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
5 ]; q3 _- z5 p# Q9 x( \! k<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
1 [. ]5 f6 {$ ]0 w3 o6 |: ?( K* ]. z<P ><FONT face="Times New Roman">}//while</FONT></P>
( J& L& k) U. u0 T/ [<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
$ a; a4 A* @# L" G$ X  Y, |<P ><FONT face="Times New Roman">}//if</FONT></P>5 C& B6 \3 [$ r1 B( `, [- q
<P ><FONT face="Times New Roman">return –1;</FONT></P>
; X' Z8 s+ C' @! A<P ><FONT face="Times New Roman">}</FONT></P>
  a4 P, q* V6 K0 S; \<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
! Q3 Y* N  t  A/ ^<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* @% g2 b. @% |  c3 B<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>  z/ C( p4 v% x- c* v( a, k& ~
<P ><FONT face="Times New Roman">{</FONT></P>  g! r& W7 E" B3 t  T7 q
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>3 q( A  b! X+ X, `/ Z
<P ><FONT face="Times New Roman">              {</FONT></P>
9 M/ x0 ?5 E1 q) O  @* a( Q% j<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>7 b* B; X+ N8 V3 P( B
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>9 H# E9 x$ q$ Q( R
<P ><FONT face="Times New Roman">              {</FONT></P>; ]8 k+ U. B8 y/ |$ v; H. W
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>" C8 G9 G- s, ~
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>( S' i2 I5 h9 d" a0 w
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
( W* j! i9 h* x<P ><FONT face="Times New Roman">}//while</FONT></P>" J& B% ]# Z& m* h
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
; k6 m4 f7 l7 ~* w; V  c8 o* @: k<P ><FONT face="Times New Roman">}//if</FONT></P>
* Z+ a$ k& d& C; p<P ><FONT face="Times New Roman">return –1;</FONT></P>7 e+ A) j4 Y. D+ R
<P ><FONT face="Times New Roman">}</FONT></P>, j8 v' ~7 f" X1 p3 v% m& O) n
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 x$ J+ ?! K/ _4 h- w0 O<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* @, _7 B1 Y* ~, H- x6 D<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>" e% m7 U, X$ f& d( I- m0 U  q: \
<P ><FONT face="Times New Roman">{</FONT></P>
7 A8 j, y4 {% x& e) M+ ]: ~* q<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>9 d. F) Q1 H! Y2 Z2 j8 Q/ o
<P ><FONT face="Times New Roman">              {</FONT></P>
( M9 F2 L4 p+ j1 Z  m; g<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>. Z# a0 P1 y2 e; A
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
3 {' \. M  C" Z. B$ x1 d$ F( m<P ><FONT face="Times New Roman">              {</FONT></P>
  y/ L$ ~  Z; h& f, Q, o" T<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>! W% I, U6 X4 h
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>* ?4 I- y* g7 O1 i) q
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>6 |  M0 h. V( R. v! B! I. P
<P ><FONT face="Times New Roman">}//while</FONT></P>
5 r) ~, L* V0 i<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>9 s+ U/ O! K5 K& m2 R! j6 Z) w
<P ><FONT face="Times New Roman">}//if</FONT></P>
# u6 U  u8 S+ f4 x3 |; s<P ><FONT face="Times New Roman">return –1;</FONT></P>
, E8 Q: }7 A0 }<P ><FONT face="Times New Roman">}</FONT></P>
2 |, x/ G8 G1 p4 Q2 d2 S& t4 r<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>0 ^0 B* V" Y* N9 O0 u
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>( ^5 u& c1 c' f3 V( x; h2 J, b. k
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
6 D% n. j& j% U8 C% W/ m<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
! k$ E  |( q- c. g2 v<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>+ T) _. H% M' H4 a6 l8 _# n/ w
<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>' F) T& C$ V! |) w/ `
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
- g6 o6 P1 C3 L0 P+ g# g2 F<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>8 |/ V3 |& Z7 ]9 S: X
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
; t& Y/ p: }& z3 a  A, Z* K+ |# r<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>! t# A, I- g6 ?6 h( c) g9 Q
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
3 @! B) K1 x' |<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>
% N- a. d1 U2 h  X; l+ n' `<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
% A) N9 t& l% h7 g<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
% M; k/ a$ B! a! _, v, _5 N- _0 b<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>
' C" R; Q7 ^6 B& a8 a8 Q<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
$ D3 X2 Z0 |4 E) c# U/ f8 ^$ S<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
. X9 E" `3 g, O4 ~& k8 s. m: J<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>" a, f+ M, c9 r0 \5 f
<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>! h5 E0 ]7 L8 L9 C6 s6 n
<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>
8 a, m) V9 e0 d9 Q: F/ l# v<P >即:middle &gt; left成立。<o:p></o:p></P>3 L/ z' K# J$ o2 z9 Y( R+ _0 x
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
5 m4 B9 t+ R% e<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
6 ~/ W) g, ~$ n6 @3 i0 c3 ^<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
' w: I5 [$ u8 k<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>4 t9 |/ X' ^/ R* r
<P >∴返回结果正确。<o:p></o:p></P>
7 ^9 I& }4 l% b! z; n9 N4 B( x<P >(6)算法6是错误的。<o:p></o:p></P>9 p! T8 }% f+ c% t* Q- b
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
. U- I1 A2 ^. k& i<P >left = middle + 1;<o:p></o:p></P>) j4 Q9 ]: N5 S# ?& L& h& g2 F
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>9 n' T( W1 W8 T  j" X
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>0 P4 F0 b% H: p, S
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>' Z- f- K; L$ Y! B% @" K
<P >(7)算法7是错误的。<o:p></o:p></P>
" o) y: Y3 b) h$ Z9 @7 x<P >在循环过程中,一旦出现<o:p></o:p></P>) H; b. |: h5 u! ?8 T) d. Z% W
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
3 ^! a% F( |) M& a6 ?* |# ?<P >原因:right值的修改不正确。<o:p></o:p></P>




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