QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2901|回复: 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>
$ m+ ?( T; k6 \, s( \1 ~5 p& b+ x< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>" ^4 R  Y  ^7 Z" @1 z5 n& K
< ><FONT face="Times New Roman">{</FONT></P>
5 o- \8 P% s, c  I# R- }< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
( f: X2 m! c  x5 G< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>7 U/ _) F+ h4 L, U; ?
< ><FONT face="Times New Roman">{</FONT></P>
8 H7 E, D' e1 w8 `. F! X< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>7 ]! S( N/ k% G
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
* V0 G8 u2 s( u5 P$ _8 _2 r6 N5 R& n/ Y, H' e< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>9 o7 `) u$ X6 K: f# B$ U9 u" v
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>* L, F. C8 u& j! P/ h6 `! k
< ><FONT face="Times New Roman">}//while</FONT></P>
; E$ b1 X, p0 j2 o+ z< ><FONT face="Times New Roman">return –1;</FONT></P>
) v2 V) `! u; ^* _# }; ~< ><FONT face="Times New Roman">}</FONT></P>
# x' Z0 P0 d+ y* J/ r< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 Y7 U. \3 v1 w
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* \  {6 D" w8 P7 I< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
( ^6 @' k5 O: g. o. @: ]8 E< ><FONT face="Times New Roman">{</FONT></P>
/ k# k* Y! w1 B! u< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 _+ N$ l% @0 y) J< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
0 n0 H; J0 g6 D8 z- c6 g% W< ><FONT face="Times New Roman">{</FONT></P>+ `8 n" _9 J) D" }
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
  O8 V% V8 z7 B, c4 l2 x< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>3 ~, ^6 _5 T0 l( P$ J/ F
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>( E$ ~4 M8 z2 q& P
< ><FONT face="Times New Roman">}//while</FONT></P>- H' h: d! Z; |7 C* C. M5 S: b
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>  j1 v& p( s( m8 J
< ><FONT face="Times New Roman">else return –1;</FONT></P>
# M2 u4 h+ k  t( y9 l! Q3 I< ><FONT face="Times New Roman">}</FONT></P># P) Q  n/ B3 r6 G
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>! A7 I! ?3 U5 H6 e
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>; \. m; f+ o3 i3 I+ `) Y# s
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>/ N! V/ i+ H$ X
<P ><FONT face="Times New Roman">{</FONT></P>
% l) h# P7 z' n0 O1 U' R' y4 ?5 d1 {<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>+ r! g* V0 _" B5 }+ Y- \3 ^& c
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>" r  C! z+ G' f. N" e# u! m7 X6 s
<P ><FONT face="Times New Roman">{</FONT></P>8 c! B  ^" _  G  w3 }% V
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>/ R+ m! k# X( {( J
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
, B% {0 j% t1 z4 Q<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
, K1 ^1 b: p! G* |<P ><FONT face="Times New Roman">}//while</FONT></P>: q/ V; I1 v% \& Q9 p
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
9 C4 B2 m2 a9 `5 A2 |- O1 E<P ><FONT face="Times New Roman">else return –1;</FONT></P>
; K  n7 s8 C! O, K: k<P ><FONT face="Times New Roman">}</FONT></P>( N! w3 N% l# W& q7 Z1 h; W
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' o9 I3 ?: `+ ^2 \) Y  J; U8 W. M
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
7 Z' P7 e& m: H! m+ M9 S<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
: W! W8 _; I% }; Z<P ><FONT face="Times New Roman">{</FONT></P>
2 W, E7 n( n9 n0 R, ?8 S<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
) E! d( U8 b! O<P ><FONT face="Times New Roman">              {</FONT></P>
4 Y: _' H/ z7 q* }8 S) S) M! i: D) V8 r; ?<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>0 r- v( W- H" h' e. R9 l
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P># B* `" c0 ?7 x6 {0 S/ w) B6 W
<P ><FONT face="Times New Roman">              {</FONT></P>% T5 p5 _- Q# @/ S
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
0 d5 b* ?0 ^1 @+ m. [. W<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>, M5 u9 W: F$ Z  k1 t
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
' A, s( z7 N/ P: d7 c* M<P ><FONT face="Times New Roman">}//while</FONT></P>
7 r7 L% f! p9 q" |" K1 Y<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>' i6 ~4 {% y0 y! w  R) _
<P ><FONT face="Times New Roman">}//if</FONT></P>9 M( P& r$ O6 c9 v: d9 q0 v
<P ><FONT face="Times New Roman">return –1;</FONT></P>( o' [$ G2 r2 o6 G( Y" W" P
<P ><FONT face="Times New Roman">}</FONT></P>$ O+ }1 H0 f! e% s
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( H, n* o) I# `4 A! K3 R
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
& r( }2 t7 J* L) W/ V<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>7 A& C9 W: ?' n. s4 i6 Q! A0 M
<P ><FONT face="Times New Roman">{</FONT></P>
- N6 q2 I# S7 p<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
( V. g' t4 M0 H8 ?, N: `( {" j<P ><FONT face="Times New Roman">              {</FONT></P>
; j' m  S7 J9 u' v; x9 |/ n<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
7 k2 T& E  S8 s9 l2 q3 q6 e3 {9 t<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>" x* X6 y( a2 s- N$ l
<P ><FONT face="Times New Roman">              {</FONT></P>: ?. ?  a; c% w8 ~% ^; l
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>. u1 e# W; }( F# F: y/ z! E4 A
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
: C0 `0 V8 B8 e, K( U; a# X<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
. T/ p7 L# n; O  X  s! v; F<P ><FONT face="Times New Roman">}//while</FONT></P>
# w" w$ x& A" s1 M3 M<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
( D( Y2 g( ~( ]# y' |, \+ _2 q( X<P ><FONT face="Times New Roman">}//if</FONT></P>! o5 @  u( x* a( m
<P ><FONT face="Times New Roman">return –1;</FONT></P>
! B- ]& J+ J0 `% |8 W; z<P ><FONT face="Times New Roman">}</FONT></P>, ~& s' f5 r( [. N) u
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>3 f8 I3 p; \, |1 t8 o: ^! t
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>1 Q+ `9 j) W' f- Z1 q# p( d
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>6 Q: \7 N+ {& n* E2 ~
<P ><FONT face="Times New Roman">{</FONT></P>/ W4 `" V. N! q& o# ~
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>, |; T( Z/ `  U, _  Z& ^  V
<P ><FONT face="Times New Roman">              {</FONT></P>
# ], O5 m* x2 B! z0 C# ]4 m: y<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>$ k# L0 n# c/ W. O
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
6 n* E$ [3 [9 |- r) j2 K$ P2 Y<P ><FONT face="Times New Roman">              {</FONT></P>
- d' Y% `, a0 h8 f! F<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
8 M: v" |- a4 o/ J3 ?<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
/ X3 F( z/ v. W& D0 k<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>5 ]6 j: ?2 Q. `" A4 a1 Q
<P ><FONT face="Times New Roman">}//while</FONT></P>
: r& G" N4 L& {) V<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
5 r% a1 S# `+ Z$ u+ _5 `, X* A<P ><FONT face="Times New Roman">}//if</FONT></P>0 }% [$ [  n# k+ l
<P ><FONT face="Times New Roman">return –1;</FONT></P>
2 _- ~! c' b) k$ \$ V<P ><FONT face="Times New Roman">}</FONT></P>0 r$ l7 q/ ?/ c/ I9 l8 K4 u& _5 h
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
/ D: s5 S. C0 o/ d, i: f3 z<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>$ {& k0 k. }) P4 b
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>6 u" R$ ^: a' a2 o: C- S( @% t2 m
<P ><FONT face="Times New Roman">{</FONT></P>
( ]# N( V# v' }<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>% V# o  N& w4 H! S
<P ><FONT face="Times New Roman">              {</FONT></P>  ]+ J+ g. B) u* a3 P4 d+ \- t" H
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
1 f6 Y: o, {& F0 S<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>3 a# f0 ]* H( M9 C) s
<P ><FONT face="Times New Roman">              {</FONT></P>
9 m. r- C- }2 j5 u' l<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
9 ^9 B% y' x* a3 `& k<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
+ j- @; A2 B) m) t( O' o/ y$ d<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
8 K8 I( F  H1 h" f1 O* U1 N) V' E<P ><FONT face="Times New Roman">}//while</FONT></P>
  o1 u1 F  c8 |/ B<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- x$ d# n- h& H6 O) k
<P ><FONT face="Times New Roman">}//if</FONT></P>
: S, x% V& H" r$ E1 f8 ^& l<P ><FONT face="Times New Roman">return –1;</FONT></P>2 H# I" @1 |' u* k0 p# A! ?+ H
<P ><FONT face="Times New Roman">}</FONT></P>
  {' d8 b1 F9 @; \# I- F$ k<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% o( @5 S, E8 }7 C) a
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>7 e# b' e1 ~, x
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>. z4 N# H, [+ t' v$ D
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
8 c1 A5 w- [. o, {- b<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>  v" |5 m% [3 j1 \! c. M
<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>; z7 M5 [6 O! w9 H5 [. a
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>! o, ]6 P9 A$ o8 [, L2 N  P4 C
<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>/ l( w4 h& m) Y/ U5 \) O
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
" S; Y9 y4 G/ _/ [: ^+ v) t5 X) 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>% v5 u5 T( s6 C) w! m) B( z1 g
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
& Q8 U) x) ?% f0 D<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>/ {2 J) M2 R( V
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
6 M( ~7 ]4 a$ @<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>! H; ]3 R( M. g3 p. Z! f/ J
<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>
5 F* R) q5 P; f<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
1 ?. m# h3 _! a( V* {<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
5 s3 v# R* e; a<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
4 N! l- g  j" z# k7 ?6 R9 s( G<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>
+ \( _$ Z  E; _* E8 g- D) N<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>
0 P6 h* L) B" r! ]% F- v<P >即:middle &gt; left成立。<o:p></o:p></P>) x% \- h/ _4 D( ~' {; y. B
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
) S  F- [0 g4 R5 T) V# [<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>* v' ?) l8 T- l& [$ S$ N. R
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>" ~' a5 ^9 F# h$ w* y& N
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>4 C, w0 T; }5 S% I4 z1 G+ U' i
<P >∴返回结果正确。<o:p></o:p></P>
9 {& S8 J4 s5 a7 C6 A& [% @& n' i$ B<P >(6)算法6是错误的。<o:p></o:p></P>7 A! l! F, F) }7 @
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
1 Y3 J. ?, v+ d<P >left = middle + 1;<o:p></o:p></P>4 c7 [( t6 q/ S2 k
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
% i6 A- h3 |# H1 A7 C/ G! G<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>. I/ N- Z0 i; j2 |, R
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
1 X4 _% `1 R4 z% ~% S1 i( z* M<P >(7)算法7是错误的。<o:p></o:p></P>* f% A" J, G. j- m
<P >在循环过程中,一旦出现<o:p></o:p></P>% L9 g  S9 Y' H# [$ R! `
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>- M. w0 D: K/ X9 G7 A
<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-25 04:45 , Processed in 1.304895 second(s), 51 queries .

回顶部