数学建模社区-数学中国

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

作者: 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>
# _; z0 z1 o8 @4 R6 l1 T5 `2 w< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>4 w! @  W" M, ]7 {
< ><FONT face="Times New Roman">{</FONT></P>
: e$ P8 _& b/ V1 M3 z& L< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>8 v' m( F+ |! y" Z. J
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>' j! t0 o# ?$ K: C* }+ B
< ><FONT face="Times New Roman">{</FONT></P>! h8 U8 h+ l5 k' x' D( _3 A
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
) L/ Y4 E) ~8 \* p# J. G1 ~< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>4 L' O* l( b& k) z
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
. F. c# t0 g# n6 W< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
& X7 l7 {6 I# p/ {  J7 r< ><FONT face="Times New Roman">}//while</FONT></P>
' k. w' m# h. u: a) A# U! u; E) O< ><FONT face="Times New Roman">return –1;</FONT></P>8 g: k: ~4 I1 C" ~
< ><FONT face="Times New Roman">}</FONT></P>
/ O/ b* [, @; r: ^  b# t+ t9 o< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>: g8 z# C( P5 a  e! L) j! W
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P># B$ @! G! x4 k" Q
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>$ f2 j$ I8 O) [3 p4 A
< ><FONT face="Times New Roman">{</FONT></P># ?2 v/ _- A8 L6 f5 x
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 f8 u* s( g* f, j& m< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>4 p8 ^4 d0 r. I# _% d0 ~
< ><FONT face="Times New Roman">{</FONT></P>6 s3 Y9 V; C7 h3 F% Z  {+ Z6 R
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
% p+ C" I+ p( y9 [* |; I' m- L* |) h< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
$ x( k+ A) i" Q6 C, ]# Y1 y< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
5 F/ k8 R; {1 G6 i< ><FONT face="Times New Roman">}//while</FONT></P>$ |  r# v# Q. o- T. m
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
8 e) J) Q$ s- l8 z< ><FONT face="Times New Roman">else return –1;</FONT></P>
5 u( j8 |* z& Y! l: K5 f- a, D3 R< ><FONT face="Times New Roman">}</FONT></P>& t! ]+ x% @) c$ \7 U
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' r5 @: O2 j: y0 w& a4 ]! z
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 v7 f, h( D. C1 I; ^< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
' R! h0 s2 M$ y2 B* ^<P ><FONT face="Times New Roman">{</FONT></P>
, q/ P& F8 b6 i- H9 j% B9 h9 L7 e<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>1 i) B, |4 }: q$ }
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
( a4 Z7 G+ b9 y8 p; Y* @" S, P3 X<P ><FONT face="Times New Roman">{</FONT></P>
* O, |1 r7 p2 K<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>9 k- N8 |8 E1 F$ k0 q! s
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>% [3 y6 u0 Q" ?
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>7 c' y) ?( _% u; T9 w; Z5 G
<P ><FONT face="Times New Roman">}//while</FONT></P>& \; X% G& O  }3 K; H- r
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
+ a5 J! @0 X0 k; r% T: @- U<P ><FONT face="Times New Roman">else return –1;</FONT></P>
0 n: U3 }/ l4 S2 D; Z( y4 S<P ><FONT face="Times New Roman">}</FONT></P>
) G3 [% @( u/ r<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
7 @/ H+ d; z  N# T<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>6 e/ \' W8 M# H$ @6 J- C" D0 t
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>% t' n# B: i) y, c3 q" _: T$ J5 e
<P ><FONT face="Times New Roman">{</FONT></P>
, c2 X6 X1 h1 q5 F<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>; w5 v5 w* o7 |6 n5 q
<P ><FONT face="Times New Roman">              {</FONT></P>
2 h& n1 G% `+ U<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
2 q1 C/ q+ {( l: K) L' V* e( I<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
6 c3 B& P) t& o9 P1 S$ n<P ><FONT face="Times New Roman">              {</FONT></P>
. e, A+ V. R" a) k( C( b0 J: h<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
" L5 t  b: S; `<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>1 M3 Q7 T) k. r' l3 v; y+ W
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
9 c& Q: m' s7 O: K# K, S<P ><FONT face="Times New Roman">}//while</FONT></P>/ i$ p6 K2 P! k% X. K6 x% |
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>+ ]  a* g- }$ P, r8 ~3 r
<P ><FONT face="Times New Roman">}//if</FONT></P>
( j* m7 N( {6 X) _<P ><FONT face="Times New Roman">return –1;</FONT></P>
* k  H' M4 B: N. R: q" r" i7 @+ E<P ><FONT face="Times New Roman">}</FONT></P>- z2 U1 Z$ N3 v: `0 f$ H9 w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>: z, ?+ O# q1 o4 W5 p2 E2 p
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
$ r2 h) X8 k( r<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>! }. `6 d, H' ~( I" z" ?
<P ><FONT face="Times New Roman">{</FONT></P>/ A. I0 O/ c3 w# d( x: w; P
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>3 ?& G3 z: B4 G& l# ?; `" p5 U
<P ><FONT face="Times New Roman">              {</FONT></P>
+ Y- w% R+ o" `, J<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>1 S" R! w' g% ^+ \% y
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
3 \: a/ q1 s1 B" G3 b* n3 C<P ><FONT face="Times New Roman">              {</FONT></P>
9 s. l# I) @2 v6 L<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>$ h3 s0 ~7 b) M7 v4 E) u- p
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>1 c7 N/ m4 q+ j0 m9 U" ~
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>) _" n9 P5 n2 R$ w/ g* F4 P; H0 _
<P ><FONT face="Times New Roman">}//while</FONT></P>
5 N9 H, b  z& o<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>8 _! X% q1 ?1 `+ _+ |  W9 n
<P ><FONT face="Times New Roman">}//if</FONT></P>
* P$ x" t0 C4 A% }# [( j: U6 J<P ><FONT face="Times New Roman">return –1;</FONT></P>
, \4 C6 Y) j# @4 k<P ><FONT face="Times New Roman">}</FONT></P>
+ e, m9 E+ d& K, z<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>6 {% \5 R( K; ^; ^' c
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ H) _  j! S; V( D3 I# L& Q<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
- ~9 J) v. _% x4 r- r<P ><FONT face="Times New Roman">{</FONT></P>
6 u) d4 m- D" R<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>) x  T% t+ F( o
<P ><FONT face="Times New Roman">              {</FONT></P>
9 ~+ b, A; g4 M; s) `% y. y, k<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
) {, W) ~2 w% P( U: Q$ s  @<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>" N0 Q- r7 p) _: K2 c
<P ><FONT face="Times New Roman">              {</FONT></P>
' e) l3 k+ ^: z  W; a) T3 q<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
  ~) r; e& c3 k8 d<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>2 n  ^6 \' v) {  d& L
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
" e3 R' `" j! R$ P, @' x; @& P<P ><FONT face="Times New Roman">}//while</FONT></P>) u& w4 ~6 R- A; D8 E
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
+ X& N3 T4 K/ t4 B$ H2 g5 [<P ><FONT face="Times New Roman">}//if</FONT></P>
; d9 M  a$ C! u<P ><FONT face="Times New Roman">return –1;</FONT></P>
* P% ^: @5 w# P8 {% L+ i<P ><FONT face="Times New Roman">}</FONT></P>5 B" m# K7 g1 R4 m" j- L% ?
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 m5 I4 J6 u& j) T
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
4 y9 _7 G- I. j0 n2 j* E( l% m. A<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>9 ?. C6 l  s' p# Y) v- F
<P ><FONT face="Times New Roman">{</FONT></P>
1 T0 D4 e6 Q) A2 l9 n  M<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
( e/ j# H7 U2 w4 F- [4 H<P ><FONT face="Times New Roman">              {</FONT></P>+ I& _% h5 F$ y
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
: C4 m$ j& {$ P<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>) D; Q8 n$ q1 J6 w7 |, p
<P ><FONT face="Times New Roman">              {</FONT></P>
+ j- q5 i4 T' B& T<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>  u/ D& ?- A* @
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
0 L0 U' g/ a8 b: U<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
: V+ Q% z5 k( G% k/ K<P ><FONT face="Times New Roman">}//while</FONT></P>7 G! d  Z8 Q( @! ^1 P
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>: A. |3 u5 X1 u9 K$ l
<P ><FONT face="Times New Roman">}//if</FONT></P>
: U$ [- m5 n  |9 U! @  {9 E<P ><FONT face="Times New Roman">return –1;</FONT></P>( Q5 t5 G- [' ~
<P ><FONT face="Times New Roman">}</FONT></P>
- F" _- \; x5 o0 e4 u) d7 }9 A<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, g# @) g  k- _* u  F<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
5 u0 u* I+ M" |' V) k<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
1 K7 l6 P4 N* ]' I% r$ }4 m<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
7 q! ]) b6 n. m4 F% U<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>2 u4 R2 u/ h+ Z" G: H
<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
3 P; }& l& w" h4 D! I<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>+ D  L( v; X. G, l4 R+ O& b8 X/ s
<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>* H+ x9 o9 r; b+ m2 X0 e
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>. D# U; X/ y- _: O; H* ~# w. G# [
<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>
! N. b$ {( }! _. ]4 i  T% h  m, t<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>1 `' m: v) i1 q) ~
<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>9 t/ Z7 F# Q4 N/ y# N
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>. |. @  H, @$ Q1 B% Y  A! j) w2 H
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>1 o. K3 k: ^( S" M4 A, U! a; T
<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. X1 t6 z' C: N<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P># o, j7 Z* M& ~3 q; A$ e
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>/ p! S$ P  f2 u5 d5 }, E
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
+ @& U& }6 W! f8 y5 W, K<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>
. M! J3 p% c% D<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>
0 n$ S/ A, P3 p<P >即:middle &gt; left成立。<o:p></o:p></P>
6 o3 e3 e) z" P* y% K2 _<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
% T$ w# O% J# b: W, H<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
& Z0 }. G) J# ^" Z- n<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>" X' d0 ]# B' F" g: w: s
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
) E) y6 |  ^6 n% J/ ]9 q5 w<P >∴返回结果正确。<o:p></o:p></P>
/ J8 @* {/ b: k4 y- P0 n<P >(6)算法6是错误的。<o:p></o:p></P>
2 P  \9 W! k2 s, [<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>0 T: _$ P4 y/ G6 K
<P >left = middle + 1;<o:p></o:p></P>
( y8 F( Z' v* V& S8 n2 o1 B  b<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
- }4 I1 ^) a) F: m4 }<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
& P( @& V' @8 e4 v+ {6 I4 o! Q<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
6 X, S0 G/ q# }3 p4 |* ^! |. l$ y' w<P >(7)算法7是错误的。<o:p></o:p></P>
- g& h' D7 T3 U3 X; t, D* w<P >在循环过程中,一旦出现<o:p></o:p></P>0 n* n  c% P1 C$ a; D; x; f7 K
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>4 p; L8 c+ p  |: D
<P >原因:right值的修改不正确。<o:p></o:p></P>




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