QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2903|回复: 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>9 x+ g9 }  {" ^5 }
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>- i% G) x; k" H/ h7 }+ M8 h
< ><FONT face="Times New Roman">{</FONT></P>
) K* E6 r1 y8 U1 ~< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>% b# g5 y# K) s( X' Q2 |
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>, P9 J1 K; H- o! P) z( D* r
< ><FONT face="Times New Roman">{</FONT></P>
7 A  t+ a' v$ P9 l1 Q  G< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
/ ]  u$ Q; N) |< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
' P. T+ g4 d3 @2 Q: g7 V8 P5 e< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>7 Y, y$ j' o3 l% P
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
( x. T9 |) h1 P< ><FONT face="Times New Roman">}//while</FONT></P>
5 r, V  t6 t: j% {3 d* }+ E6 R0 y< ><FONT face="Times New Roman">return –1;</FONT></P>
, |' |1 _" v& I8 E& J6 G< ><FONT face="Times New Roman">}</FONT></P>+ [  t, k5 s! |; X2 ?! k
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: e( [2 C! ]: l0 e5 F) y< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
6 J2 y) C- r# D7 A< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>6 l+ F- M, c/ ?
< ><FONT face="Times New Roman">{</FONT></P>3 H7 e2 k$ ~/ M1 K+ [
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 R  D/ _) V3 w+ R, N/ V< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
) W2 r* ]" V8 ]! m! _5 ~+ m< ><FONT face="Times New Roman">{</FONT></P>' {+ a7 ~8 x/ O, k# B( h; L! H0 ~
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>: i2 l" e5 n  L/ o
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
- D& N6 \: }, `: S3 v2 K& t< ><FONT face="Times New Roman">   else left = middle;</FONT></P>& w/ _$ I2 R7 }
< ><FONT face="Times New Roman">}//while</FONT></P>! F* ]2 V) [' \7 C6 X" l
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
6 b2 t" R3 D' k3 f< ><FONT face="Times New Roman">else return –1;</FONT></P>
, o/ P% v7 g! f) ?< ><FONT face="Times New Roman">}</FONT></P>
$ \0 i! v2 a( v3 u; p0 e) q< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) X( B3 X( d% A; t* m. S
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: F4 o% a% }- f0 ]: A5 l  C- ?4 l$ n< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
. B4 i3 ^* j. i<P ><FONT face="Times New Roman">{</FONT></P>
& D- q. ?8 Z) i<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>% A$ ]9 m! ^8 ?& R3 i4 U6 ?9 c
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>; z  P8 M3 X7 s. u$ D# E% Y' E
<P ><FONT face="Times New Roman">{</FONT></P>
" a6 A8 s. y4 u( P4 o<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>- ^6 G% T' q$ U- q, q
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
. H8 ?. v6 v( E<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
0 l9 `8 g# y) `& _1 ~% o! o<P ><FONT face="Times New Roman">}//while</FONT></P>- @+ r) y! B4 ~) v
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
# S5 A* ^/ w0 y+ k2 v- y<P ><FONT face="Times New Roman">else return –1;</FONT></P>
9 n5 A& p! o) e6 k7 s<P ><FONT face="Times New Roman">}</FONT></P>
+ v' o/ p- }& S( Q: j<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 Q/ c. t2 O0 d+ U<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
- F" N# h! X$ I<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>$ c9 U/ E& M% K4 Z/ z
<P ><FONT face="Times New Roman">{</FONT></P>
8 L& ^. {/ w# S5 ]; Y<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
- ~+ i6 S  M% m4 I<P ><FONT face="Times New Roman">              {</FONT></P>
# Z7 z" [7 N& O; l; Q) L$ M& n+ o<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
/ n, }% W1 n/ `# T<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>( p5 f* |5 s3 z' e4 O5 y
<P ><FONT face="Times New Roman">              {</FONT></P>5 Q1 p* D* g$ r0 K& ~* W
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
0 D+ I( g0 \3 v  h. H& s1 w0 ~<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
0 X/ k) g6 b2 Q4 R) _3 |<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
7 T% l" h. z( q5 D+ w8 B# h3 l<P ><FONT face="Times New Roman">}//while</FONT></P>  |- p2 y2 P, M4 u2 F" j
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>( n" R+ O2 O# B
<P ><FONT face="Times New Roman">}//if</FONT></P>8 J7 E- I4 b6 \1 D
<P ><FONT face="Times New Roman">return –1;</FONT></P>
% E# @' x2 M# {+ Z3 t. D* ^<P ><FONT face="Times New Roman">}</FONT></P>  o4 c# ^' l$ `/ y0 C2 @1 }; W2 Q
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' P) ~2 b/ @: a. L0 ^
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
8 b3 }6 R9 K) y6 M7 ^<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
& K' K' A. ~6 b# `+ W" W) }- c6 }% o<P ><FONT face="Times New Roman">{</FONT></P>
+ T7 {$ }- Q7 Z<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P># R; W* f4 x6 _- J
<P ><FONT face="Times New Roman">              {</FONT></P>
7 J- e7 E: A, D/ N<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>( d  z8 ?6 |7 s2 r& v) w
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
5 ]: M9 H; H' }. n" ?<P ><FONT face="Times New Roman">              {</FONT></P>: m% _/ _& L& _0 h* W
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
% K6 Q& H9 F% L  K" O<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
5 U/ a! z  ^5 j+ h1 P<P ><FONT face="Times New Roman">else left = middle;</FONT></P>; S1 o& G/ {! o4 l/ @
<P ><FONT face="Times New Roman">}//while</FONT></P>
" R. W4 D3 c% }3 \- e<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>" H# C: {1 a% \: [% A8 z! H3 F
<P ><FONT face="Times New Roman">}//if</FONT></P>
2 B, ]3 {' Q, y  v. M- f<P ><FONT face="Times New Roman">return –1;</FONT></P>) ^9 W; ^! ]' ^# @; F- }
<P ><FONT face="Times New Roman">}</FONT></P>& s& L3 ~: h! ]) v6 }. f
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
/ t4 q: S3 U, T, C- R<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
- [9 H" ^) s$ ]2 ~5 I, V<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
8 Y" Z& a4 t! v3 t1 ?<P ><FONT face="Times New Roman">{</FONT></P>* k' t1 J; p2 j6 y' \
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>% f; ^2 c# L0 E4 F+ }
<P ><FONT face="Times New Roman">              {</FONT></P>/ U+ O3 F% m5 C' N: u: B, \
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>  }- |8 e7 u, \, N
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
/ B( J. ^8 v* V4 B/ I<P ><FONT face="Times New Roman">              {</FONT></P>* J; Y# n2 K! i- m
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
) p5 F4 F2 K, I5 F<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>9 v' o% y  O4 j8 f# j. z; }
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>" e; v$ `; L, V6 F- f; Q2 P4 {4 _0 \1 j' |
<P ><FONT face="Times New Roman">}//while</FONT></P>4 }9 _% [* T! n( [" E
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
" W) P+ E/ v/ h0 J7 W<P ><FONT face="Times New Roman">}//if</FONT></P>
1 J/ J) ^" ?* V5 w. J4 r  F. {0 c* d7 B<P ><FONT face="Times New Roman">return –1;</FONT></P>
4 e' S- s1 \3 k0 ^1 T0 s<P ><FONT face="Times New Roman">}</FONT></P>1 O* Q& r$ ~- w- ~' f1 L
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 W/ n/ |  ^  \* b7 f, l% Y
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P># V! Y+ n7 Z7 Z: }9 z1 l
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>( c7 X* D- c9 b" E1 ^; G  Y
<P ><FONT face="Times New Roman">{</FONT></P>
/ y$ T- x. ~) L<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
; d/ a) E9 h7 `- k. D9 x8 j<P ><FONT face="Times New Roman">              {</FONT></P>
- x0 J; |; `! f' [2 I) M1 P1 w<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
+ w6 B4 v6 e# L; K$ s<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
, }0 Z0 T8 \9 I8 R! C) k# }" d<P ><FONT face="Times New Roman">              {</FONT></P>' K- J! z0 E& H- P  ^0 d3 @
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
+ o6 @  R! U( V7 U% f<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
# c' N8 F7 W- F. N- |<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
: r. W3 L7 U6 t2 B% F<P ><FONT face="Times New Roman">}//while</FONT></P>
0 Y0 }& \0 H  g& a% J/ y<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- n+ c5 b. T5 H% @- t
<P ><FONT face="Times New Roman">}//if</FONT></P>
3 J6 T4 L+ M. u  F8 ]( Y: N<P ><FONT face="Times New Roman">return –1;</FONT></P>5 Y$ M7 i1 ?4 S
<P ><FONT face="Times New Roman">}</FONT></P>2 b& H5 {5 O( @" {  `; o
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>$ |3 G( ?* Y2 Y/ z2 Y5 ?" o, F
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
0 n% B* n/ x9 U& G9 A! m# b<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>. W7 G0 X: I* Z- I
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
# K  V- n8 q# N) F" }3 h<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
( \) T! |$ j0 V7 i<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
4 h/ p! z! h' N1 w( P<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
6 N) l9 H. @8 i. F. a* p  ]. S+ {, o  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>$ J' i" _6 z+ A4 M; z5 @2 y
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
0 V4 t* o( u0 r5 ~. S<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>
. {0 t+ c* x- v; k<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>8 q/ ^# L, M' I7 ^1 ^
<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>
. Z% o0 C, d2 r6 h- ~+ `# X1 [* `<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
& l+ Z- _; N1 b' D/ X/ r4 f<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>5 ^- [, M/ Z$ ^3 @7 ]& Y) @( U6 f0 g+ f
<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>
# O% e) I/ u# V' x* h<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>3 \0 a- S8 ^+ P$ C/ G
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>0 m# |) B: x2 E7 c* L7 |* D/ ^6 _* W
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
* X" K) e9 t$ k. b8 M2 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>
  F1 J" X1 p. u% i5 j; 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>1 T. I; U2 A1 F
<P >即:middle &gt; left成立。<o:p></o:p></P>4 F7 M9 Z& Q% j0 Y0 T# q
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
' |$ L0 Z7 v9 y8 ^* W" x# p<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P># k7 p8 D# t: K" M1 W
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>( I/ d2 p! P% C; s; u# C9 z
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P># j2 Z: K* f! Q, q  L5 F
<P >∴返回结果正确。<o:p></o:p></P>  y7 n8 J& r/ g- [7 X- {
<P >(6)算法6是错误的。<o:p></o:p></P>
/ [/ N& P2 ]7 N4 B4 E<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>3 o0 i# ~. y. b
<P >left = middle + 1;<o:p></o:p></P>; x: i* C4 J6 h1 z5 P
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
9 r' w3 T0 t0 N<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
1 s5 ]( ~6 F/ K3 e# v3 r3 d& G<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
+ k9 C* N! Y- v4 e" `4 D9 }; F<P >(7)算法7是错误的。<o:p></o:p></P>& E3 H8 J  F, y. U; O# U+ _
<P >在循环过程中,一旦出现<o:p></o:p></P>; G4 u5 k# x0 T; a: r
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
7 i, @5 C9 l, w9 m* K/ Q<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-10-26 04:09 , Processed in 0.373584 second(s), 51 queries .

回顶部