QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2895|回复: 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>4 E& K: U  l" ]+ a/ ?
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
" R( V+ E& q$ w/ J< ><FONT face="Times New Roman">{</FONT></P>
: @' R: n( k& f* N7 j$ l- m< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>/ a# ^- S7 k% C- q( R
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
+ i# G' u1 E: X< ><FONT face="Times New Roman">{</FONT></P>
( K" K: x) b8 Z2 x1 f/ p< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>! l- P- S" S0 D: u# g# ?! }
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
$ x$ e8 @4 l  w( _4 B< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
4 J) C; u! d. ~. R7 H; F# E# m/ L< ><FONT face="Times New Roman">   else right = middle;</FONT></P>  v- w. Z6 n0 r5 |! l; Q
< ><FONT face="Times New Roman">}//while</FONT></P>
0 [, p. r5 u& A& }9 ~3 r1 J< ><FONT face="Times New Roman">return –1;</FONT></P>2 R/ h4 J) `+ k$ {- l
< ><FONT face="Times New Roman">}</FONT></P>
  g. X$ `2 P( y9 X5 I; }1 {  E< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' ^/ ~, z9 O. c/ @
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 x- T/ o. d6 s9 C# t* d! f
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>0 I$ z2 Y4 m2 p9 }
< ><FONT face="Times New Roman">{</FONT></P>
$ r: i+ i2 `& H- F& @< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>; G3 d, n; h. _
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
6 S3 j4 B2 F6 |/ g% @< ><FONT face="Times New Roman">{</FONT></P>
6 y' [% u9 ?" a! a& \/ C< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>% I2 W) L, u- Q0 e& X( \9 N/ ]
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>8 Q/ P9 I9 |" P) ~$ f* Y
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>" }- ~  v& R7 s9 I5 a
< ><FONT face="Times New Roman">}//while</FONT></P>" C3 }* }+ X& ^- \4 x4 R
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>* G9 ~3 e3 U8 y* r3 ]) z- M
< ><FONT face="Times New Roman">else return –1;</FONT></P># D; g- E* A/ Q2 c" E, @
< ><FONT face="Times New Roman">}</FONT></P>" Y; K2 z2 Z# \+ K0 A: O! l
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  A  g  p1 G7 y' _< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>& ~* ^/ Q7 ]8 |  r! i
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
" Q9 w4 z. h; [" B5 o: Q<P ><FONT face="Times New Roman">{</FONT></P>% j& C6 d- e; u
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>' s3 `4 \- i* u/ P3 u- }
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
1 {3 T/ Q$ z3 c: u<P ><FONT face="Times New Roman">{</FONT></P>
, ~) m1 E" ?8 }8 M: K<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>8 J# x& ?9 |! P6 [) q, S
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
' o& d2 ~. K# Q6 v( o( p<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
# a, O3 Y/ L0 G+ M. p- o4 H<P ><FONT face="Times New Roman">}//while</FONT></P>
2 _! P1 b* M+ g& s1 G3 m<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
! y% i* C2 I' P9 k; A3 }% a; J<P ><FONT face="Times New Roman">else return –1;</FONT></P>
- U% U; z3 K/ p( p, I/ F0 l* n<P ><FONT face="Times New Roman">}</FONT></P>7 Z' v) C  h! E8 \1 O( _" T
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" I+ g) I- X3 h: I) ]4 Y1 d0 Q" Z  S<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) L3 B* Y% i5 R- F) j! a, A
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
) D- D: i- K& q  G<P ><FONT face="Times New Roman">{</FONT></P>2 y0 U' i( U+ Z9 o
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
" T' z7 n  V$ w* I7 I! i& H<P ><FONT face="Times New Roman">              {</FONT></P>
+ ]# T* h+ \& P$ R( `<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
: l& z. e+ u3 `$ \<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
. D5 y# ]* v, y/ Y+ y<P ><FONT face="Times New Roman">              {</FONT></P>  U/ A1 |4 y; Z: I/ E
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
( x/ K, p; }& g/ j4 n" {* G<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
; P' _& @4 T# K- X: B' I0 F<P ><FONT face="Times New Roman">else left = middle;</FONT></P>, a. [. @) T5 I% |" j
<P ><FONT face="Times New Roman">}//while</FONT></P>
. R# H9 e/ C! `2 j2 E0 L& W( R<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>0 J+ |- l! R" T; ?8 X0 d9 ]8 H
<P ><FONT face="Times New Roman">}//if</FONT></P>
  X3 X- |+ o( C<P ><FONT face="Times New Roman">return –1;</FONT></P>
6 {1 s: R. Z0 z4 h6 `3 e. q6 J<P ><FONT face="Times New Roman">}</FONT></P>
. b3 n. q. h6 k  s' \; _& }<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" G5 e1 d! X9 j/ l; q" W2 t<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ s; N" P9 l( I( p
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>5 ^& U6 n$ y: }7 I: e
<P ><FONT face="Times New Roman">{</FONT></P>
8 p2 r9 Y- G+ m: F<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>; Q( O6 y" a7 s! t/ ^& o
<P ><FONT face="Times New Roman">              {</FONT></P>. G5 _  w* c/ m9 n
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>: _" g3 `6 C2 S' A
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
, f( ~+ {8 U% t0 a3 {<P ><FONT face="Times New Roman">              {</FONT></P>; p4 E8 x1 ]' x" d. O( O7 @
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
* [3 O8 g6 S& O- \# ]7 T. ~<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>- q7 @8 _6 `3 S( R" S1 t3 F
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>' I9 c4 d' a% e$ K
<P ><FONT face="Times New Roman">}//while</FONT></P>
1 K9 [9 Z7 i  e+ d7 ?<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>! Z7 t* u6 v' [" u: Q( i" m" q: B  o/ i
<P ><FONT face="Times New Roman">}//if</FONT></P>
, p8 c9 X; f# V2 M% J: }& j<P ><FONT face="Times New Roman">return –1;</FONT></P>
2 J% V) C" N6 E: f5 _! Q9 L<P ><FONT face="Times New Roman">}</FONT></P>* F! Q) Z* A( }: Z8 L, m: Y
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ }1 l& Y! L$ V7 ^5 Q
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>; I1 M$ D2 M1 v0 B$ y4 H* U) q
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>' S' v- A0 h2 `( `
<P ><FONT face="Times New Roman">{</FONT></P>
$ V: W3 ~/ S2 V<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
& {& m* b( P" x0 V$ Y<P ><FONT face="Times New Roman">              {</FONT></P>  a% s$ P2 b" m' y  H/ r% m
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
0 k; ]/ r) a# m' U' X<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
% s! ?7 `) A1 l7 e( Z  B/ D<P ><FONT face="Times New Roman">              {</FONT></P>
0 ]5 k8 ~! ~* w0 e$ a, ?6 ]; g& }* _<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>( X$ C5 H$ e# J. d9 i$ d
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
8 |; ]* ^, B: G4 p/ Z<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
% E8 K  h* b3 x9 c1 E, o<P ><FONT face="Times New Roman">}//while</FONT></P>. I% @1 G/ p! [9 Q; a! n8 k
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>' J* Y6 W3 w  W  g
<P ><FONT face="Times New Roman">}//if</FONT></P>  b2 ^( N8 O5 a; _* y" q. Y) \  \
<P ><FONT face="Times New Roman">return –1;</FONT></P>0 @& q, Y# X9 ]) ]" b# h6 r; A: |
<P ><FONT face="Times New Roman">}</FONT></P>' t3 @. |/ }* d" o) S
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>: b( ^* J, _% g8 s) S6 K. D6 u0 d
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ I" E8 A' n* T  h8 Y
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>& u0 i0 D! l5 Y* u9 {
<P ><FONT face="Times New Roman">{</FONT></P>& Q- M7 `4 g- L5 r9 V
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
; M/ U3 _9 Q% l5 G! f( y4 Y  U+ v<P ><FONT face="Times New Roman">              {</FONT></P>) B! H% h) K5 q4 S* z1 A" w
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
/ r8 n# [9 B9 `) ^<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>, t1 A# M% C( ?* w1 Z8 Y/ g
<P ><FONT face="Times New Roman">              {</FONT></P>
5 J5 m0 m- d" p# ?<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>, ]% z2 w# g& L' ?: Y
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
7 J$ t1 V+ o5 b# ?<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
7 ~5 \2 Z# @, k$ ]. T' ~- L8 q<P ><FONT face="Times New Roman">}//while</FONT></P>
% k% z7 \; p6 f8 D  i7 g<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>! M! m9 _# z! [% l5 X- f! F8 a  I
<P ><FONT face="Times New Roman">}//if</FONT></P>+ t; _% t6 C1 a( \
<P ><FONT face="Times New Roman">return –1;</FONT></P>
9 t8 v; _$ I, f* z<P ><FONT face="Times New Roman">}</FONT></P>- {2 ^  h% R. B" \. @
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 R% @: i3 R8 p* P7 U
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>% I' Z& X/ f- l
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
8 m4 c. i( q' Z6 ?# }<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
1 j# H% t! L$ k<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
" @" `, U$ C7 c. e<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
: ?8 i0 o# T+ ~4 }0 M2 i0 ?. d<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>. \* L% S  k' s8 f# ^: K, D
<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>
5 \+ j9 U  b4 _% e2 W: s<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>3 K8 M5 I& M$ Y$ 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>
, b# V" I- `" u% {3 q1 {9 ?<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>: ^8 J$ }+ Y( A1 ^! g9 f
<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>
! T) T$ v/ G$ b7 \' g) L<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
( `- Q! T/ b) D* g& A9 {<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
4 w0 {( U8 ^: F, j0 Y: p0 `# n6 ^<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>
; h' y: D( v1 A' ?7 D) v' |, \<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
. @# H& ~$ ?3 x2 t<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
% Q$ O& q/ }6 t& i<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
$ F* C2 q3 {. e1 y3 ~<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>
" |& |) r6 l! v, X<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>  P2 W2 z, ^7 n' y. n- ^9 c
<P >即:middle &gt; left成立。<o:p></o:p></P>
, K! F( b3 x) N8 U4 W+ z<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>' E, f( V& `. Y0 S# l
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
' q% w# j& u! w$ ~) t) R<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
4 u1 K- D, [9 Y& M" O& c<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>6 o" m/ ~- q; _  |# r
<P >∴返回结果正确。<o:p></o:p></P>' `( J! v) ~( e% \
<P >(6)算法6是错误的。<o:p></o:p></P>
8 y$ T3 X* J# E  g/ V<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
1 B( N. \/ ?& w2 P1 e6 G! T0 c<P >left = middle + 1;<o:p></o:p></P>! N- P! l4 p* t# E4 _7 k
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>1 [5 S# E3 K9 R* @% w
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>7 \9 u* c/ m( q8 T/ ]
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
5 u; x$ M: x& _$ U<P >(7)算法7是错误的。<o:p></o:p></P>$ h" Y+ e" h* U; b# @9 t3 s$ r9 e) Y
<P >在循环过程中,一旦出现<o:p></o:p></P>
  t# P5 Q; Q! s) u<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
' v8 N# m. m& {/ ^7 i! c" n; |$ ?  f<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-23 09:29 , Processed in 1.214375 second(s), 52 queries .

回顶部