QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2834|回复: 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>
. D! {: X0 p* W4 _< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>* n$ W' M" O6 p5 b# s. Y* `6 T
< ><FONT face="Times New Roman">{</FONT></P>1 r  P, V* {) I& ~
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
2 i: t, u& c: R& ~0 {% ^$ J5 {* a< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
3 v! {% z9 |% x/ ^< ><FONT face="Times New Roman">{</FONT></P>
* G4 U/ P2 D/ \) Z< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
; C+ s+ Y8 Z( S8 O4 t& `5 A/ u' h< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>& p$ {: `" P1 Z
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
" b& V( p& ?0 _4 U7 r: x. ?, n< ><FONT face="Times New Roman">   else right = middle;</FONT></P>1 g* X% `9 P- F1 t( y* ~
< ><FONT face="Times New Roman">}//while</FONT></P>9 }3 J$ P6 s: }$ q  b7 I
< ><FONT face="Times New Roman">return –1;</FONT></P>
5 I. u6 t4 }% `/ F$ b< ><FONT face="Times New Roman">}</FONT></P>5 F2 M. T  i  B+ V4 c* e
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>: O' R5 }  |1 u; s
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, k& r, n/ y7 r# x2 L0 O# s< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>, M" c6 b! X4 G5 E
< ><FONT face="Times New Roman">{</FONT></P>5 P- M5 _. ?( y/ L9 x/ g  `3 d# {% ~
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>. i% M5 L0 b! h7 k3 g" M3 [
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>7 B- B/ N  @( R+ O& Z
< ><FONT face="Times New Roman">{</FONT></P>
3 [( Y& y3 v& ~8 O# C) ]! [< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>, q# a/ v: D# {5 N% {! q( l$ |$ N; ^
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
/ D6 N0 S! i+ n7 G5 @< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
! E2 l8 ]8 A* A9 T* U< ><FONT face="Times New Roman">}//while</FONT></P>7 C$ Q. _# g% R
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
7 v! l2 }6 S3 I! b8 Z# v5 j< ><FONT face="Times New Roman">else return –1;</FONT></P>3 g% Y$ c. w% @, Y( h4 G, t
< ><FONT face="Times New Roman">}</FONT></P>
( O" m% M8 ~$ F7 A< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ h& j8 d4 I: p5 b" B
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>. S7 N1 R4 ]( O8 Q6 I) _2 _8 O  a
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>( u* S6 n4 E' p% l" V" w
<P ><FONT face="Times New Roman">{</FONT></P>
# ?+ Z7 q  ~* N7 X<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
( {5 q8 h4 I3 ~1 m5 v" V0 o, V' J4 F<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
" Q; c' g9 k  H# H( ?8 d# E<P ><FONT face="Times New Roman">{</FONT></P>
2 I- F* d9 g5 A& O4 v<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
3 P/ N: s6 L% l, F! B+ g  f4 W2 ~<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>1 M! Z: x3 _6 R. y: m0 ?
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>$ q; d$ Y6 p) W3 [4 i
<P ><FONT face="Times New Roman">}//while</FONT></P>8 B$ z/ {1 P7 U
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
8 ]5 J8 E& J( b<P ><FONT face="Times New Roman">else return –1;</FONT></P>& d7 w' r5 I, V/ t! \2 }" R) s
<P ><FONT face="Times New Roman">}</FONT></P>0 J( x% q4 [& s/ b4 ?2 w* Q5 C) s; E
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  o! x! |8 m% W! ]/ P: @7 a<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>9 A& H' |) e+ ~- n1 B- G9 a
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
' o/ Y2 |* }5 p- z<P ><FONT face="Times New Roman">{</FONT></P>
- ~6 i; L. N- Q; Z, ], a, b  _<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
9 _' E6 W+ C: W8 i6 B2 P<P ><FONT face="Times New Roman">              {</FONT></P>
4 R; g3 d& z6 o+ g0 h<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>2 u" K: F# R1 Y2 D$ T* a
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
4 B+ c4 C% q$ o8 c$ C<P ><FONT face="Times New Roman">              {</FONT></P>% b5 l7 F4 @) {, {9 C* ~
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
# C1 Z, f' i7 |& g* q  h<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>% H8 N4 x) `& g% R
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>' ~0 S; v  Y" G( S. o
<P ><FONT face="Times New Roman">}//while</FONT></P>
, n$ Q& I5 h" `+ E- r- L<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>5 ]8 F) g5 ?3 K# t
<P ><FONT face="Times New Roman">}//if</FONT></P>3 j' ^+ n2 i3 r
<P ><FONT face="Times New Roman">return –1;</FONT></P>+ a2 X; d  n& m
<P ><FONT face="Times New Roman">}</FONT></P>
) z/ Q/ g% g) V4 e& p<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  \9 a  z& z% J/ {
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. J% f7 N' N& [6 Y<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
; d$ q9 ]1 \: t2 v<P ><FONT face="Times New Roman">{</FONT></P>1 {; h6 b( t, c& O. w* k' O
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>2 _- F& k* `; g: c8 O0 o* x+ t
<P ><FONT face="Times New Roman">              {</FONT></P>; W7 n. V$ j# w" n& W; c! t
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
# A  p( \! \  @<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>0 O, Q3 q( b5 p" w8 R3 h
<P ><FONT face="Times New Roman">              {</FONT></P>
& _! C2 K0 f$ v<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>( H3 G' {& J8 Y; v& I  |- X2 T( q
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
  |- ]' l7 r3 v) t& R3 f<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
6 I: M2 F7 ?/ d; V1 h& i0 Q  X6 `<P ><FONT face="Times New Roman">}//while</FONT></P>/ h' y1 H8 N# j& s3 r0 H. d, l4 N
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
# ^9 A" g) C  ]) R! ^$ ?<P ><FONT face="Times New Roman">}//if</FONT></P>
$ C+ z) C" ~; A* U% `# y<P ><FONT face="Times New Roman">return –1;</FONT></P># i" R2 K8 D* B( W. n) Z' s
<P ><FONT face="Times New Roman">}</FONT></P>  q6 V; y  Y" _" {$ U
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>7 q+ @( I' r2 U2 d2 j2 b
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ [# t5 @. q# H7 O5 D% T4 Y
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>4 r# w+ l  |3 @9 A5 f
<P ><FONT face="Times New Roman">{</FONT></P>
" A6 F6 d& \% l* c- M. u' h8 Z1 p. T<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>5 W2 o# ]; A3 ?0 D9 i8 r& j. i
<P ><FONT face="Times New Roman">              {</FONT></P>% H! U  l3 n% n1 f; _
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>* c/ G, l) l) _7 G
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
4 n$ T3 ~4 M, T: r: N$ H1 D<P ><FONT face="Times New Roman">              {</FONT></P>
8 b* ?3 W" d. `) V5 K<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
3 ?4 A) z  c- r5 R4 x$ U1 c) m/ m<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
" D6 c, i/ q- t  u9 Q' Z3 l<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>* e; K! D4 Q5 ~0 N  a. x
<P ><FONT face="Times New Roman">}//while</FONT></P>; [1 P- k, {% a* L
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- t: x( a* J* [9 a1 _4 G4 d6 m
<P ><FONT face="Times New Roman">}//if</FONT></P>- r0 R/ c! N5 s& V* V
<P ><FONT face="Times New Roman">return –1;</FONT></P>
9 P# d5 [; C! O* R1 c3 C' J<P ><FONT face="Times New Roman">}</FONT></P>0 ]. C% N( Y' w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: a; U7 p/ y" |- [* x<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
9 A1 u. F/ K/ q+ P<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>" U& E( K( w( d8 E6 O# D3 a( b
<P ><FONT face="Times New Roman">{</FONT></P>
! V7 z  E0 o( E4 q0 M+ b<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>$ p$ }2 q& D, ?5 O) Z3 Z9 \9 X
<P ><FONT face="Times New Roman">              {</FONT></P>( Z- N! ^7 N; t  Z3 F
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
. i/ `1 }* U0 @<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>8 x6 ]( [+ l6 t2 |7 M- H( T
<P ><FONT face="Times New Roman">              {</FONT></P>
+ z4 A; X. C$ Q& C4 ]<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
; I1 K: C1 }% i# g<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
1 V& Z- W( d, E/ q<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
7 B6 e6 \* m& m. F0 v<P ><FONT face="Times New Roman">}//while</FONT></P>, P$ W( Q& V, f) k
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
/ c) O1 c3 `; l<P ><FONT face="Times New Roman">}//if</FONT></P>  V/ e% s4 g! `0 x% M$ H
<P ><FONT face="Times New Roman">return –1;</FONT></P>
! @$ V; E+ ]: C' f( F1 p<P ><FONT face="Times New Roman">}</FONT></P>* q* J; w$ A* K8 o% J5 y" f
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>7 |8 t* C& L" x% B
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>$ i: b3 Y  [$ j! U8 Z$ z( R6 Y8 P5 M
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
8 l) {' ?$ \# l" N<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>9 q9 |' R& O+ L1 E5 p. ~
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
1 h8 o+ ]& [' U' p! b9 j<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
! K, l& x2 H- K; j. i) G! L<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>4 l" V) c* ^* I8 L; e2 T; Z0 K
<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>' G6 z; o+ G! c. m' ^" e( z/ g% t
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>4 Q, R# M; [8 ?
<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>
% G4 m/ w& X+ A# i- g1 i' ]4 d<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
' U, c$ A2 G6 G, d0 C<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>. ^. n0 I3 b5 M0 }( ^! S4 ?
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
' d3 d' y. `/ J" R4 V<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>1 j8 C# v$ y0 P3 O$ H! u0 V/ ^: 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>
$ @$ D  i1 ]% w5 y<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>" d( h' p  L! k  t6 D
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>  c" G$ Y9 L& K0 R
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
! n1 `% `* C$ d( j5 r( a<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/ q' Z# z( @! w  X9 k. f8 y1 G<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>  f7 _8 f1 o9 |8 Q) Z/ F
<P >即:middle &gt; left成立。<o:p></o:p></P>
4 p1 }9 N+ i- y# y6 c<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
& m3 }$ D4 e$ C6 |4 l6 h% Q7 f<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>. F+ g8 V. b0 V# E- \- `8 Y
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
$ L& t' \5 P! Y<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>& w6 P" a5 D  R6 V8 |. Z
<P >∴返回结果正确。<o:p></o:p></P>1 y" |& Y* Y4 \7 |3 o) u0 J# t4 B0 x
<P >(6)算法6是错误的。<o:p></o:p></P>( j0 u& g* i" L  U- z
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
3 [# |2 }3 b' w( C' b<P >left = middle + 1;<o:p></o:p></P>8 M; c, _' Z$ k4 W& }3 I
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>& K4 {( E1 \: G8 r1 g
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
( Z. `* W# ~3 n; W- Q/ F<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
* l4 ~5 G, `1 ?6 `<P >(7)算法7是错误的。<o:p></o:p></P>
- N- }/ N- A  p<P >在循环过程中,一旦出现<o:p></o:p></P>6 l; q: [' Q5 O- T+ C) Y, V
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>( |/ `% {- J) r" K. Y, K
<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-7-21 01:37 , Processed in 0.833880 second(s), 52 queries .

回顶部