QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2814|回复: 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>
' y+ l! D2 J$ r+ f& k< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>, A5 l( j: h9 y( R1 h
< ><FONT face="Times New Roman">{</FONT></P>
  M' Z2 x9 V5 V' B; P< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>& x4 x* N3 t! p" M! G
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
; v4 f1 C) s) ^/ F( g- U< ><FONT face="Times New Roman">{</FONT></P>
/ |9 U2 S/ }" g% o! u) e  S  L< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
' q5 O2 N8 F! }< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>  M! ~, t% k" f( a4 m
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
$ w8 W7 V, N, l/ v< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
2 c+ w, |9 F5 r5 z9 p2 a9 }7 }< ><FONT face="Times New Roman">}//while</FONT></P>
; j! u) z$ Y: m- F< ><FONT face="Times New Roman">return –1;</FONT></P>  T0 C7 S: |' m6 z2 G2 ~0 ^7 z
< ><FONT face="Times New Roman">}</FONT></P>( H3 W$ B3 \  f; C2 Q3 J) o" u
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- b7 M0 T0 q  ^0 D
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>& g6 u3 j$ ?. ~$ k3 C6 Y2 X; M6 f
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
& E' Q% E) s) K/ Y5 B< ><FONT face="Times New Roman">{</FONT></P>$ w5 g1 T/ _! y+ R/ ~. X
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>( U; Z# ~, N4 f3 A7 N4 F9 K
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
9 W: H& ?+ o7 J# B  B< ><FONT face="Times New Roman">{</FONT></P>5 F; f, q# a; |8 i8 }+ q  j
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
0 Y* H$ }/ _' \+ z) q  Y< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
3 G4 H0 f; S1 _# B) F* z$ b< ><FONT face="Times New Roman">   else left = middle;</FONT></P>) [8 `% {6 M/ v$ H
< ><FONT face="Times New Roman">}//while</FONT></P>0 L6 x; Z- y) ^: `! I: [
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
) c0 ^7 S! u7 B7 s< ><FONT face="Times New Roman">else return –1;</FONT></P>
* y6 \+ k1 G3 K; J0 l/ O< ><FONT face="Times New Roman">}</FONT></P>6 r% E3 @, o, P5 U7 @5 E6 |; ]
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
9 b/ w/ S) T% a9 F3 p& q< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% ?. U5 u, l( i4 _. O
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
: i" ]# `6 a8 u; x# x<P ><FONT face="Times New Roman">{</FONT></P>* J6 U/ U0 W$ b% ~* w0 s9 A" ?
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
% B* g2 V, @/ O3 }! e<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>/ a5 }' J# b8 B
<P ><FONT face="Times New Roman">{</FONT></P>
9 [* h9 P& q- ?; ]+ {<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
) |! }- R7 n' c1 N" N0 {<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>+ M- s, C1 `% D
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>; T( f$ R3 B4 A
<P ><FONT face="Times New Roman">}//while</FONT></P>
. W1 P7 s  T7 w, d8 _: t: g<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
! u* C' D1 p0 h3 d/ Q3 U<P ><FONT face="Times New Roman">else return –1;</FONT></P>" ~% o: ~2 I+ n9 x
<P ><FONT face="Times New Roman">}</FONT></P>, y! O5 e- [9 \, I/ Y4 e  d
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% C5 P+ l& W  @$ }<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 Y9 i, u! t* q" U# ^) s
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>2 l; z5 C8 l* H, g! b
<P ><FONT face="Times New Roman">{</FONT></P>9 H9 b( n% L3 g1 [; J. \( m. @# A3 v
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>  |: {4 i! Q# a! S5 X+ I
<P ><FONT face="Times New Roman">              {</FONT></P>
2 E; M1 @6 V7 d; o/ c( W6 @8 z<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>( N! f0 T1 O0 x. h& f+ ^
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
# J" |4 q$ d0 G; ?<P ><FONT face="Times New Roman">              {</FONT></P>
) F3 H, m- @( l8 O# t; ?<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
0 M( f5 Z' o. W4 w& n- s5 X  r5 _<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>; {: ^3 D* _( H( L3 F# N
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>0 {, d" K3 [0 w
<P ><FONT face="Times New Roman">}//while</FONT></P>( \! K" q7 c, ^' g  H6 K
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>, e1 `% q* p. {6 D* w& i
<P ><FONT face="Times New Roman">}//if</FONT></P>
6 _0 V3 K  z& d<P ><FONT face="Times New Roman">return –1;</FONT></P>2 J1 L4 ]8 {0 @0 j. [* v2 G9 y& Y: z
<P ><FONT face="Times New Roman">}</FONT></P>
- @8 H9 F3 @' S9 c! F/ k4 P7 d6 I<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
1 H. W: e" v% e1 d3 }( v<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ N/ f6 ?! h& @. N( \! V
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>5 k" q7 ~8 @6 r1 s5 s
<P ><FONT face="Times New Roman">{</FONT></P>
; A5 x; D# s7 p<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
' m' D1 ?% d( c* @, O<P ><FONT face="Times New Roman">              {</FONT></P>2 p4 I' |  I. h8 ^+ v1 `' o: _! m6 w
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
6 @+ N: O6 u5 j! i% U* x<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>$ G" B8 [9 n& k. H
<P ><FONT face="Times New Roman">              {</FONT></P>
. F5 j6 Z' @5 @9 r! {) \% S! v% {<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>6 _. w5 D) t6 b4 }7 M
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>! T. x# X1 G7 e8 j3 f
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
6 U# {8 r( b$ V& n( A# d<P ><FONT face="Times New Roman">}//while</FONT></P>
9 w5 j* G6 G+ c8 J<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>2 W; G: U9 T' [$ [/ S
<P ><FONT face="Times New Roman">}//if</FONT></P>
# w# W2 ~: z6 L. \; N$ P<P ><FONT face="Times New Roman">return –1;</FONT></P>
" u$ o0 Z* c' v3 _. \<P ><FONT face="Times New Roman">}</FONT></P>& ?  m6 m# f9 w) x" K( A9 {  L
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
6 n( o5 R/ c9 l# K6 I" u<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>, w1 d$ v% ?7 i7 f: B- \) P) M# B
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>  Q& ]# B" o" S
<P ><FONT face="Times New Roman">{</FONT></P>
" P+ Y9 p1 y4 P. k! }/ t0 `( c<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
5 Y) j. @$ S' J! @/ ?<P ><FONT face="Times New Roman">              {</FONT></P>
# f  F# _$ r# g; e, [( {<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>$ \- C# k& O/ K$ g. v* |- t8 F
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
; F1 |' k" v1 Y. d% {5 r<P ><FONT face="Times New Roman">              {</FONT></P># b$ b) C- G# W( F0 ?
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
% D7 E" c$ {6 D- C2 F0 U* `<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>7 j' b" y' l# z7 }0 l
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>  z2 E2 w6 x/ [: S; p0 p
<P ><FONT face="Times New Roman">}//while</FONT></P>
, i) U# w/ \2 `. Q  O<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>7 V: B' w* D. g, ~' s' f# k
<P ><FONT face="Times New Roman">}//if</FONT></P>
3 Z& d* U" X6 I<P ><FONT face="Times New Roman">return –1;</FONT></P>/ s$ u8 o: G9 e0 S* @
<P ><FONT face="Times New Roman">}</FONT></P>) c; o2 w# [  }
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>, |4 w6 g7 i0 u8 a
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
# ?5 q& B, _) w( X5 y<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>/ X. V7 I2 B! Q) {4 b! y
<P ><FONT face="Times New Roman">{</FONT></P>
# m7 v* q- A/ s8 c<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
$ q8 O; H* q2 h8 P- m' g. a+ P<P ><FONT face="Times New Roman">              {</FONT></P>
: }6 S% O9 c  }9 l3 D  `/ Y  E<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
3 R* n* R0 [& ]( i  e<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
; a6 {  j: p3 @<P ><FONT face="Times New Roman">              {</FONT></P>
6 c. V. \+ k9 ^9 f5 d<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
1 s3 @  l4 I+ @/ L, S5 e" k5 G  a/ [<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
) a# F" e/ `9 h9 Q& |<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
) S0 _* W4 `0 S0 s$ k9 r& `) j5 n% o<P ><FONT face="Times New Roman">}//while</FONT></P>) Z! ?( d2 s. H1 O* |, }0 }
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>4 v% b( `3 F0 ]+ }, B
<P ><FONT face="Times New Roman">}//if</FONT></P>
( s( a0 Y5 ?. n' V<P ><FONT face="Times New Roman">return –1;</FONT></P>
, f4 h( Z6 r0 r" ~<P ><FONT face="Times New Roman">}</FONT></P>
# C. m7 M/ }& N* i& Z$ K' N* G<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 {+ q* ^' S, x2 s7 i; [; h+ F( n<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
/ O& S. V5 T& {+ w, }8 t<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>- ^. B% D% k! t5 ~7 Q
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>+ F3 ~7 V8 d' G5 H% S
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
3 j, ?2 c* n0 D' Y; E1 Y4 w<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>5 ~% t# c+ Z* y4 D, u2 ~, x: \4 |4 o, |# A
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>9 e% @- p  b4 I4 ]. _
<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 h8 b: B; [2 {( D' h( W: ^+ u<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>; _' M. n$ u: Q* _' j
<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>
8 d5 o/ Q2 a" [' R$ X<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>( e8 R4 v7 ^6 {" G: D* l1 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>0 z! O# e) ~, F6 ]9 z
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>, k6 b6 p, z' W! D. v; _8 Z6 t
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>8 f/ `: }9 m3 M: x
<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>
1 b8 [0 b7 @8 w4 u1 W" ~<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
( F9 S$ ^: D' R3 o! z5 ]<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
# w+ I& z& n" F$ k) x# O$ O  p<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
$ E, ]) c& @# B" u( p5 }( m<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>9 q' W# C3 T2 F0 t$ g$ t
<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>
7 x# g- o% o2 v! g: P2 o<P >即:middle &gt; left成立。<o:p></o:p></P>1 T6 _- k' L) Q- p# j  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>+ z6 }- B+ a/ W2 }, R6 k  z
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>/ ~, \: v& [2 x! P& e/ f2 v
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>$ T- W! `  I; Y/ S; o% z3 r# {6 o
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
3 \- S# C: Y4 r# o) B5 E+ b<P >∴返回结果正确。<o:p></o:p></P>1 j; `: }8 R7 `
<P >(6)算法6是错误的。<o:p></o:p></P>: J3 I8 D7 S$ Y8 ?; U4 H7 H
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
8 i7 F/ n6 m% v+ G<P >left = middle + 1;<o:p></o:p></P>
: J% a/ K2 n/ w1 V) J+ \% L<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
1 y9 J- q2 _5 c; j2 {" d% a# a<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>. v5 M/ c! w' ]6 l7 k* o" C
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
& A+ }9 ]7 {4 N<P >(7)算法7是错误的。<o:p></o:p></P>7 t0 F6 g+ z8 w9 U8 n1 B
<P >在循环过程中,一旦出现<o:p></o:p></P>3 J, f4 X, ^% j+ H8 l
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>- [! C0 A3 n6 N# [
<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-6-4 08:37 , Processed in 0.434161 second(s), 53 queries .

回顶部