QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2812|回复: 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>! a( W+ N4 ?! N! f, T. B
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
1 ]- M3 l4 l7 p# T$ W< ><FONT face="Times New Roman">{</FONT></P>- f  k) Y& {# e
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
1 H4 }$ a1 q) R3 r) t< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>; J) U/ H1 X0 }8 K) B
< ><FONT face="Times New Roman">{</FONT></P>6 |4 f$ R. Z9 ^  r/ A
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>8 ]& X0 ^7 R& v6 g0 f
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
, c4 K( _0 r! v; F7 H* [< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>9 i8 ?) @9 K0 ~  m8 T3 s% Y
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>  ~) Q/ D/ P5 S, K$ u
< ><FONT face="Times New Roman">}//while</FONT></P>
6 Q. P! L8 G. E< ><FONT face="Times New Roman">return –1;</FONT></P>
  L1 ]  E' Z9 W- d! q< ><FONT face="Times New Roman">}</FONT></P>1 n( G: P( `$ t, e6 E7 {  l$ J
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>! z' N* V4 \# [: G& ~( S2 ^0 `, S
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  K2 P  Z9 @5 \8 ^4 D: [1 o; j! x& b6 q< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
$ j2 K: t9 b7 D4 I+ @! S9 m1 q< ><FONT face="Times New Roman">{</FONT></P>
8 C4 i& G# P/ q1 G< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>! S- O: V3 R- H# R
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
8 G# I7 |0 A2 I* _4 J( i: s# I< ><FONT face="Times New Roman">{</FONT></P>0 E9 O- Q: ?6 _4 o" i% R
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P># b3 Q/ j9 z6 g
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
1 t% L! m. n/ ]< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
& U* K" l9 Z8 [4 E! o< ><FONT face="Times New Roman">}//while</FONT></P># ^1 U7 s" J" G. u4 T
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
! X& D  K7 M3 C, f- r< ><FONT face="Times New Roman">else return –1;</FONT></P>
1 t( E9 t) X4 B; @< ><FONT face="Times New Roman">}</FONT></P>6 y3 k) `& s9 M/ w/ h+ z6 V) I
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* }0 |+ y- G4 d6 M4 u6 b, z
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* n0 N' L2 p" B) m: @, r9 W2 f
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
4 H; |5 o. f  k' z# ~<P ><FONT face="Times New Roman">{</FONT></P>. Z/ s) |( m& Y6 V6 R8 w% M& a
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>% G2 ^$ }& T* c( J
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
/ \0 G! W% [+ {/ A  G/ d* i<P ><FONT face="Times New Roman">{</FONT></P>0 j9 @* _: [! A" T* ~
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
% j6 K" i8 Y% f8 q- o0 G! y& E( D5 ^) v<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>. a' L) O. u/ G; D' k: Z
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>  u! D% N* V6 h% J
<P ><FONT face="Times New Roman">}//while</FONT></P>* ^4 D, C0 W6 \/ C$ W5 ~8 s0 n
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
  ?$ W( |' {! t1 ]  m5 |8 q" ?<P ><FONT face="Times New Roman">else return –1;</FONT></P>8 B8 V# k: Z0 e% e4 G
<P ><FONT face="Times New Roman">}</FONT></P>
, Y  e- T. l# }# U; o$ A<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; h" M$ y/ {8 }<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>& \, D; l. P5 \
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
% D  {/ a3 z% C<P ><FONT face="Times New Roman">{</FONT></P>
0 N2 X; j2 q2 a8 R' |1 J5 J) l<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
/ \# ]* \& m/ g$ M0 G! R( T' R0 v<P ><FONT face="Times New Roman">              {</FONT></P>, t- _" `4 ]  l1 p8 [: x2 g, ]- `
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>  _' k$ J8 B6 R2 e1 s% v6 N
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
$ y& c9 L* A! }! R" h$ r<P ><FONT face="Times New Roman">              {</FONT></P>
2 w9 D5 E( I# g6 r  Q8 A! R3 N% ]<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>) W# K' u( l: X6 x0 J! V
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>" O: P2 l. {9 v: _. I1 a, k6 h
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
$ @* i( o& i( b4 [2 t<P ><FONT face="Times New Roman">}//while</FONT></P>
# D$ ]$ l+ e, F0 U# F<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
- {9 T& [( ?; ]' ~' c* r) G<P ><FONT face="Times New Roman">}//if</FONT></P>' N8 ~  @1 K6 b" C1 W, f
<P ><FONT face="Times New Roman">return –1;</FONT></P>
* X# Q9 |- B0 c7 o- L1 l+ a+ G<P ><FONT face="Times New Roman">}</FONT></P>
* W# V& V8 ^5 i<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% c* v) R$ |5 Z* |. R6 c# r2 ^4 a<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" k2 \4 G" s6 Y0 C8 r<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>+ v: c7 w  Z6 M7 \* f) [7 [
<P ><FONT face="Times New Roman">{</FONT></P>
- Z% }0 C" H1 p% h' u. g7 |5 {<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
$ }4 [& h; [7 M1 `. w3 _<P ><FONT face="Times New Roman">              {</FONT></P>
9 }* y! t( R% S- T* U<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
5 E3 |3 a1 c4 l4 Z3 h" h0 t<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>4 k8 [8 {. _* [- b8 D1 z( N" t3 x, P
<P ><FONT face="Times New Roman">              {</FONT></P>7 M+ n) p; `& a/ I
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>) l2 ?/ p  V7 O1 d3 v
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>) K6 a+ G7 F1 p; l/ G: ~. O
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>4 p. ~! @3 m/ d7 m" }" n7 z
<P ><FONT face="Times New Roman">}//while</FONT></P>
# z8 c3 D3 x+ _) O4 @& i<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
% p" F+ ]9 I3 v* c# Q" h<P ><FONT face="Times New Roman">}//if</FONT></P>
- J  D6 o8 R" t. q<P ><FONT face="Times New Roman">return –1;</FONT></P>/ z' V3 N, J- O, z2 N1 O6 S. X
<P ><FONT face="Times New Roman">}</FONT></P>
$ W& n- j/ [& o<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>3 z+ Z! C5 W6 X9 l
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ X+ U5 x7 ^. g( P" o
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
! ^# }6 k! _5 m5 q* \& \<P ><FONT face="Times New Roman">{</FONT></P>
) z' R; [5 N+ K* O1 x/ G<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
# F7 |/ }1 [3 K* Q5 N, c* u& l: P<P ><FONT face="Times New Roman">              {</FONT></P>2 O3 s0 c% y% F  W4 d
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>! i# f$ o% M' b
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>& V: p; l; E5 ~, Z7 N
<P ><FONT face="Times New Roman">              {</FONT></P>/ C& @; a1 a: r0 ^9 f+ b. }
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
  f4 j! r& l1 V7 h  Z! [4 \9 W<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
: N1 v7 e% u0 I8 W+ H/ ~<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>: {1 h0 U& V# _3 g$ t
<P ><FONT face="Times New Roman">}//while</FONT></P>
1 u/ H4 N  e7 ]3 K- q; j& @' s2 f<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
; e  J. j) a" a+ i1 A<P ><FONT face="Times New Roman">}//if</FONT></P>& Q6 X9 J- O( f# }8 E6 y. Q0 |
<P ><FONT face="Times New Roman">return –1;</FONT></P>
- g; u! q+ H& E  F! F! r<P ><FONT face="Times New Roman">}</FONT></P>2 j! t3 `9 b4 ?/ f! w* f* J8 f
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: C# u/ B/ b& u0 n& H: W<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* b- x/ M2 M6 h# Q! e8 S4 Z
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>
7 H: B4 O" o& Q7 S2 f  f<P ><FONT face="Times New Roman">{</FONT></P>
4 v; a2 i: Y, Y. I5 j<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
3 e4 z' n" e% p  \- P* r, p<P ><FONT face="Times New Roman">              {</FONT></P>0 i, _) @% _  H
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>% }; ?0 Q- }; D( [
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
) g5 A9 R- v4 I9 t5 U1 A1 L<P ><FONT face="Times New Roman">              {</FONT></P>/ E% B+ _- `+ A6 `5 c9 l2 P' ^! A
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>. m! b" Z& [' I  p, z
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
* n6 T& p8 o% o+ f# ^3 o<P ><FONT face="Times New Roman">else left = middle;</FONT></P>. E) O' U/ O+ o1 |
<P ><FONT face="Times New Roman">}//while</FONT></P>; G! S* ^- p4 U. M" [( ]# t
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>. a+ K3 Y0 W7 x0 X
<P ><FONT face="Times New Roman">}//if</FONT></P>
6 k) R7 O, U( [: u( l<P ><FONT face="Times New Roman">return –1;</FONT></P>
8 x4 h9 L8 ~: a; w<P ><FONT face="Times New Roman">}</FONT></P>
7 h5 {$ S# L- N  Q2 a<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>0 W5 B9 ~6 l% T
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
( }9 x( k) F' G) u, L# A! k8 h<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
, S2 r$ d1 B# f. l- O9 H% E<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
: q3 c$ Q- @, L" z2 @* M, D<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
7 ~2 A" G  [4 X3 y0 L1 @<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
* J) q2 H  B1 m! h6 ^  R<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>* L; |1 V; b' S6 o) V
<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>
2 }# Z( H5 X* q<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
" @* n; z3 o: ?7 I8 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>
/ L1 `' v8 c5 `7 l+ M, J<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>6 g% U) h0 q( f8 N" S1 T
<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>
8 c6 q. y* v1 {  A, `<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
0 x: i5 k! |/ ~$ y: a1 f<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
8 J2 ^3 E0 H+ b7 X* s0 K<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 R6 P* X/ u9 y3 _<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
) J; |% i3 K/ z: e# E; N* w<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
1 ]: p3 a9 P% r; l; J/ r<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
* _" M( {6 i; Y  S$ z<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>
: P+ y# {3 A3 l% V8 U# X4 }+ p' 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>
1 n- C" H" ~8 w<P >即:middle &gt; left成立。<o:p></o:p></P>
; Z8 g. o& b& |# Y8 v" b# Q+ d! Y<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>, G1 T6 b6 q  H1 y6 e8 N3 ]- c- t0 Q
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
# O0 O" F! J8 k7 X<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>9 ]/ m" K# `  ]. r& R. q* I( L
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
( V8 D9 w+ ?. e0 M, E- b' i$ F<P >∴返回结果正确。<o:p></o:p></P>
+ @9 Z+ V# a# j, M' W$ Q  G* k<P >(6)算法6是错误的。<o:p></o:p></P>6 N6 o1 k2 c! B$ F
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>5 K" o% w  G1 x! u  H+ i2 z) A1 b& |
<P >left = middle + 1;<o:p></o:p></P>
/ z2 O. W6 _/ \. P<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P># J0 @4 K  x+ v1 {- y% Q
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>+ z# Y; D+ x  B6 w! m
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>! Q' A) K! Q' X; }7 Q5 ~
<P >(7)算法7是错误的。<o:p></o:p></P>! N5 r1 C. e9 M; L
<P >在循环过程中,一旦出现<o:p></o:p></P>
6 ^+ M; Z: V4 J$ D<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
% d5 D" Z/ F6 `: v2 O0 D5 p<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 07:14 , Processed in 0.452253 second(s), 51 queries .

回顶部