QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2791|回复: 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>& P0 C6 Q" [# b+ X# E& g2 J  f
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>% f! Z5 ?; w8 z# _, z9 M
< ><FONT face="Times New Roman">{</FONT></P>7 M3 q  j2 Q1 d4 {
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 d% y  M/ P+ X! Q+ @< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
! P* f5 \" o2 M, F< ><FONT face="Times New Roman">{</FONT></P>8 V8 I8 [; [% I; w, Q) @9 o
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
4 g) }; v$ v7 q& \< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
, F6 O7 @8 ?- l" O, |' `9 @& L< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>1 c/ o& P" [- L1 e* _
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
7 {2 \9 X* D6 A- x0 b* K< ><FONT face="Times New Roman">}//while</FONT></P>7 K# r# C: y7 U& Z* L7 M/ ~
< ><FONT face="Times New Roman">return –1;</FONT></P>
) v' x& |, P- I! b9 v4 k: [< ><FONT face="Times New Roman">}</FONT></P>* N/ w; L  Q$ t+ k/ F5 Y! T; Q
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>" ?1 ^/ U- N$ t2 }5 @1 @! |
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
! k- V# E( e, ^2 _. K< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>: ?$ @' _. i+ [/ B9 L' A( U
< ><FONT face="Times New Roman">{</FONT></P>
9 I1 ~4 P8 a( E4 ?5 z< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
# q& k3 M  @* `/ e5 Z& L< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
1 n- B- Q/ s0 Y8 j* \- \. G" M6 R< ><FONT face="Times New Roman">{</FONT></P>/ i9 A6 p4 c' q  h! {  C
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>2 N) P7 o' W2 W
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
* {5 q  m, E; f2 n< ><FONT face="Times New Roman">   else left = middle;</FONT></P>/ x" s. o' Q2 L( p' c  S
< ><FONT face="Times New Roman">}//while</FONT></P>
2 t  G' O# V* q" V  ?0 Z: M< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>2 G5 Q* `+ j$ N
< ><FONT face="Times New Roman">else return –1;</FONT></P>
5 c/ B# g7 Y* d, I) V5 w< ><FONT face="Times New Roman">}</FONT></P>
; F3 J" q; O& p( K< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
4 E) B5 m9 g  U7 h+ J# g3 @< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
' d( ?. N$ q. b* R% @% \< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>+ O" k: t9 S, r; }
<P ><FONT face="Times New Roman">{</FONT></P>, _( J: x# a# D1 J5 z2 D1 k
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
+ C9 F9 [6 x1 H' x0 x<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
9 a# J- {  J3 K7 Y8 u& T1 _3 j<P ><FONT face="Times New Roman">{</FONT></P>
5 p5 {- P  y& h. e2 D4 v# ~<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>; E* T& C. y- z% P' `7 |, c# V
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>* ?+ E$ c$ z6 ^
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
3 h/ R( v& J$ C8 q+ b8 w<P ><FONT face="Times New Roman">}//while</FONT></P>
3 z1 }: @9 H1 h% O8 [<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
' m- ^3 x5 `* P4 i# k  X) w<P ><FONT face="Times New Roman">else return –1;</FONT></P>
$ z8 L9 J: s, ?& `4 m+ C' i<P ><FONT face="Times New Roman">}</FONT></P>' i7 E6 X( [) N7 A5 A
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; O9 c) u) ~0 ]5 f2 m<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>9 C2 F7 ]0 [! Y% g
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>& ^/ ~# j. }0 G
<P ><FONT face="Times New Roman">{</FONT></P>3 P+ J; ~, T8 M& ?6 t# K  N
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
& l6 v' [# a2 _1 y4 s" }8 u+ }  j<P ><FONT face="Times New Roman">              {</FONT></P>
% s0 Z* S% }( P- L$ k7 ]  j" a<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
/ E) }0 Z' v2 j& ?6 x<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
9 Q* S* ^3 z+ n5 _<P ><FONT face="Times New Roman">              {</FONT></P>
$ \6 w5 y5 l* M. R$ @, g+ s* t<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>7 J9 V3 `$ O) @. }% Q
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>" i; A  L5 T, j/ {+ Z6 z
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>9 F3 o: |5 B8 N4 ?; O. Y
<P ><FONT face="Times New Roman">}//while</FONT></P>+ T9 m3 j7 q) I2 Y/ r
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>/ n& s. V4 Z% p% C0 o& n
<P ><FONT face="Times New Roman">}//if</FONT></P>3 v- L  r0 q) |* r1 r! q
<P ><FONT face="Times New Roman">return –1;</FONT></P>3 L4 m: ~% o: u$ G2 ^3 f6 G7 B4 y
<P ><FONT face="Times New Roman">}</FONT></P>2 P8 `  ?  U' s
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
- T8 Y) c8 M3 G+ o' I<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>3 i/ ^1 ~7 `5 K- t3 a
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>6 `" _$ a  `1 G3 |, p3 \
<P ><FONT face="Times New Roman">{</FONT></P>9 _, i; [/ e( m6 |% |' y
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
6 G% C6 J! o8 f4 h<P ><FONT face="Times New Roman">              {</FONT></P>2 o6 f* u; [- K, l; }; A0 X+ x
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
8 U1 o4 D, o* S8 G, D3 |<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
+ w) }, t& w# H: H1 y% [<P ><FONT face="Times New Roman">              {</FONT></P>1 R* n+ B' V& R8 s! n! i; c+ C
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>! V% }: j3 g9 a' U: |+ u+ T3 V
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
& c! w3 k& U% c<P ><FONT face="Times New Roman">else left = middle;</FONT></P>9 P/ H5 ?  i+ C3 u
<P ><FONT face="Times New Roman">}//while</FONT></P>9 b0 j3 n5 c3 r1 a- e
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
; d, U! G+ Q; K+ V- b<P ><FONT face="Times New Roman">}//if</FONT></P>4 x/ h! A4 x& F: k2 `
<P ><FONT face="Times New Roman">return –1;</FONT></P>) t" Q+ P6 \- i; U9 Z" G
<P ><FONT face="Times New Roman">}</FONT></P>
4 n+ n/ h" H1 @4 k% M3 X<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>8 w( F1 j1 J$ c' ^" G6 f- L
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- W( t% |" K1 N* l
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
+ _: V, S$ F/ |% H<P ><FONT face="Times New Roman">{</FONT></P>
+ h9 J+ e  Y4 U9 O* J* `; ]' A- x<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>( y6 q; Z! _- u/ e) h1 a
<P ><FONT face="Times New Roman">              {</FONT></P>
) x. ~* L  v8 I2 ?  r. r<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>) V! Y; d3 K+ F, e# }
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
  b+ S" z0 a8 Z# E" `  J4 x<P ><FONT face="Times New Roman">              {</FONT></P>
" ?+ M" p2 O7 L. Z% Q<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
1 `4 q/ O/ \* h! |<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>, P  r- g8 [5 t$ j* p
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
- g) A0 Y) N3 `6 v<P ><FONT face="Times New Roman">}//while</FONT></P>
+ W% o( S2 \7 q% C<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>4 o" s5 ~8 F4 x8 ~9 S& g
<P ><FONT face="Times New Roman">}//if</FONT></P>
! P; K, Q7 H1 ~. f1 N, m  S' o<P ><FONT face="Times New Roman">return –1;</FONT></P>3 J, s- A8 Z) G* {1 ]/ t
<P ><FONT face="Times New Roman">}</FONT></P>
7 q  y$ a) [- W8 K, S<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>7 ~- P  X8 o! W* d' ^3 v8 B) i- b0 O  F
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 e" m% l+ t7 S5 n: Y8 @<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>) r7 ?9 h4 D% V- K' N& S
<P ><FONT face="Times New Roman">{</FONT></P>. s, B6 z) B6 B; v( D2 X. U
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
$ X9 ?/ w% R4 s9 I# D+ l* U0 W<P ><FONT face="Times New Roman">              {</FONT></P>
4 H' S2 a# A+ t2 X5 [: a) h<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
3 L" q: h! i+ C  Y7 X<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>0 O8 j8 ~: h: j3 ]! ]" s
<P ><FONT face="Times New Roman">              {</FONT></P>
" o( g# [1 c, j+ \3 _2 c<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
5 y  [; T" w* J: V, v; ?<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
2 `( D6 P. {: ?) V2 S# p<P ><FONT face="Times New Roman">else left = middle;</FONT></P>, K  o* D& Z! D$ h* g9 ^* `
<P ><FONT face="Times New Roman">}//while</FONT></P>
  ]( \6 x0 n7 H7 r/ D6 _<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
) }. u- N( V' v  F7 b' H1 V  N: A) a<P ><FONT face="Times New Roman">}//if</FONT></P>
' T, ~/ }7 c+ u. c<P ><FONT face="Times New Roman">return –1;</FONT></P>
0 g/ I9 P7 B% m2 b3 u8 v, ^3 f<P ><FONT face="Times New Roman">}</FONT></P>1 i% N7 S7 z$ D
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
$ \7 S3 X9 F* J+ K- p+ a* p7 O<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>: g0 P# D$ i# M
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
7 b: G  O. Z8 v  z) j<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>3 A4 D7 ?2 p3 U
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
; Q! ^5 Q7 f) }" ?1 {: G<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>1 A6 O/ T& z& }2 ?6 s2 y
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
% n2 o/ f" u5 ^* F& A, b9 o9 u<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>7 V  u% Z$ G* B+ o1 k  |4 ~
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>+ |4 U# K5 a; s! n/ U( j4 X
<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>$ _' Y$ [" \- a# C9 n$ Z
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
( C5 @4 Q5 x) v5 L<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>3 z0 D* t0 c. B
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
& S% f$ r) r' P7 r( J8 w<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>. o3 ?  f9 B: Q, v/ ^* o7 G
<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>' m* b/ F! I4 g8 o
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
: f" E' M% l8 o' X9 V<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>( B9 E! L6 h4 a& u
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>' G% w( L3 T* h; T) f' s, b4 h
<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>1 Q& L" c/ B: C) E/ Z2 x6 o
<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>5 m/ C/ {, C; t, N( N1 D
<P >即:middle &gt; left成立。<o:p></o:p></P>7 I/ H; A. o2 h9 C. b) s
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
; n! m: t: b6 g3 d<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>; P- W* F0 R0 T1 U( U. P
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>: p: |- S9 Y/ ]. M' ]
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
  a+ \1 A" u2 C( f0 E9 x<P >∴返回结果正确。<o:p></o:p></P>$ B% u2 Z* Q) b1 E1 j
<P >(6)算法6是错误的。<o:p></o:p></P>! l/ J9 g8 e0 M4 t0 I7 E. T0 n( U
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>3 l  O- A6 F( E2 V9 C3 ~
<P >left = middle + 1;<o:p></o:p></P>8 A; o2 C! g: a* v1 R0 W9 c
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>7 s, V/ N6 Y5 F
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
7 ]8 |, [4 P5 R# H5 X/ L<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
/ G4 P8 B; D+ E+ M<P >(7)算法7是错误的。<o:p></o:p></P>
% B. v' b( S; E" z<P >在循环过程中,一旦出现<o:p></o:p></P>% ^4 W# r$ \/ N, L) }, x
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
, S! B5 F; [% _1 j<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-4-20 06:24 , Processed in 0.290276 second(s), 52 queries .

回顶部