QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2772|回复: 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>6 P% q& l- t+ x) e- Y8 i* U$ l) r  O
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
' X! \, \* ]7 f: [- F) T4 j8 D- Q< ><FONT face="Times New Roman">{</FONT></P>- n. ]0 I) L8 p9 X0 G' x
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
: s% n1 X& v: F7 D) U4 U% Y- ~* A< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
" }8 c: S# X9 r% D1 J6 `- `2 `< ><FONT face="Times New Roman">{</FONT></P>2 D* W; f9 c$ ]5 ?% f0 S& ~" ~6 K& j
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
  Y% U2 H, \1 v1 M4 i< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>  k8 |* N# d1 ^$ K
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
* R9 ^& ~; @: j3 Z8 `* ^7 j2 T< ><FONT face="Times New Roman">   else right = middle;</FONT></P>+ C, |4 M3 W* y( }+ K* I, H
< ><FONT face="Times New Roman">}//while</FONT></P>
4 ~, Y" K" N7 B" ]8 b! N< ><FONT face="Times New Roman">return –1;</FONT></P>
1 z( _  m3 I& i  O1 V; r< ><FONT face="Times New Roman">}</FONT></P>
2 ^7 x% Y0 u( i2 i7 j) i% z, t< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( r, F% T' n) m# Y8 A
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>" [9 ?8 s# @3 H
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>1 S, o! z* {# e, E
< ><FONT face="Times New Roman">{</FONT></P>
! s( G: S+ L% N  e< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
; v( |5 H" H! j< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>+ r( h( a+ h; Y6 j" Q4 y# \
< ><FONT face="Times New Roman">{</FONT></P>
( {9 m0 e0 s2 n2 L! i< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>$ I! }4 }6 s, W: E4 c
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
5 ?& \3 W+ f" g< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
7 j+ j* j- ~6 x+ R" F9 t3 N1 p< ><FONT face="Times New Roman">}//while</FONT></P>6 s# F6 Y) N8 o
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
2 s( n: _; l- ~1 Y, M2 J* D< ><FONT face="Times New Roman">else return –1;</FONT></P>: w7 ~( o/ E/ m) _4 x! q+ k
< ><FONT face="Times New Roman">}</FONT></P>
3 U+ n: h0 ^9 b! K( D< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
$ u( H, @6 n& W$ ~# f) K< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
' p5 l) [% ]& k& t< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>" C" g9 {4 v( B+ c/ S7 W
<P ><FONT face="Times New Roman">{</FONT></P>+ S  d- M2 ]- G; A$ ~5 {
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
: i* k/ D! Z, D' b# `- I( ^; I<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
9 @1 B0 S9 L9 P! K" U' L<P ><FONT face="Times New Roman">{</FONT></P>
9 h5 `  R9 f7 a8 l; ~* ^8 [<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
8 M/ s" K  t1 {* {; D<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
1 ^( X( f5 I+ }# n: r/ R<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
! {$ @7 E0 L: E6 Z8 c: W+ m<P ><FONT face="Times New Roman">}//while</FONT></P>
7 g- @9 a7 B5 V2 Y<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>, a6 u7 Y' h( Q4 X0 c/ L0 k
<P ><FONT face="Times New Roman">else return –1;</FONT></P>
& G: m* [% T& I. R: O/ F/ R<P ><FONT face="Times New Roman">}</FONT></P>
1 H& w/ A" z( d1 D<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 g  @: N% K" `7 K
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- l2 h* p$ ]; U0 w' l! o4 z: m/ i
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
$ I7 q, W+ T1 D3 _9 k2 T8 R<P ><FONT face="Times New Roman">{</FONT></P>, }- K$ L5 _0 R  h% J
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
( X4 o' x5 Z) c( f. `3 k<P ><FONT face="Times New Roman">              {</FONT></P>) D7 D+ L' _' [4 L7 l5 B
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
8 m. A8 I3 ]9 {8 n/ r& C<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>" j' U1 f/ R' M) [( y# C& _# F$ z$ f
<P ><FONT face="Times New Roman">              {</FONT></P>
/ L. h. _, _6 ^<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>3 ^# S) P) Z+ n. d# H" x
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
. M( E3 F% z8 ]" e3 @6 i- M<P ><FONT face="Times New Roman">else left = middle;</FONT></P>1 }6 ?8 X' }& h4 {' Q5 x! u
<P ><FONT face="Times New Roman">}//while</FONT></P>" B0 C' E- G( B, j+ ~3 j
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
) V0 z& ^$ z# h) m0 h; i( E4 [* L<P ><FONT face="Times New Roman">}//if</FONT></P>
$ T1 n% s! [# ^8 n  \: r<P ><FONT face="Times New Roman">return –1;</FONT></P>) h- d: {* ?* f$ a; C& L) S6 U3 S8 j
<P ><FONT face="Times New Roman">}</FONT></P>
  z1 c% z3 F: M  f<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* p/ m: p1 T& u' J1 k3 W% P& l: O<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; O7 u7 `7 N' i, j8 G  I4 z1 r<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
4 E5 h1 c3 X: f  \8 G; D& i$ }<P ><FONT face="Times New Roman">{</FONT></P>
. D  h! v8 k- A5 H  d/ A! R2 m0 g<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
4 r  p  {4 {" r: e4 n<P ><FONT face="Times New Roman">              {</FONT></P>$ ]: I# l8 t3 i* ?8 a
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
3 k! z$ F! D" r" u1 m' I8 G<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>  H/ [. H: b1 x: G( x' p
<P ><FONT face="Times New Roman">              {</FONT></P>
8 b4 J' x( }5 J; N, k<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>% s: F# \7 B, z3 @& D0 {
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
5 N; |; p) R2 l8 S7 V( K<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
3 U5 U. |. ~% k  ^  t* ^<P ><FONT face="Times New Roman">}//while</FONT></P>
& v* \) ~1 I4 e<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
& v4 a) u: H" l! @2 c% ?<P ><FONT face="Times New Roman">}//if</FONT></P>$ ^3 y( l- F' K' A; [4 f0 ?
<P ><FONT face="Times New Roman">return –1;</FONT></P>5 \+ w4 z& D7 A/ y* V* q
<P ><FONT face="Times New Roman">}</FONT></P>! L9 a3 I% I& [: |4 Q* v& a
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  M9 U" Q' o* ]& \7 k
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  s6 [$ s9 m$ U, ?
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>, i9 h' d# I" M0 X
<P ><FONT face="Times New Roman">{</FONT></P>5 f% e3 T0 W- G9 Z: j( x
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
4 B& y9 D* A& ^2 Z7 {<P ><FONT face="Times New Roman">              {</FONT></P>/ O& k5 E1 S+ H2 u( Z  V6 b
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
" p3 j: @) }8 _( [6 \<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
  c6 l" X/ ?$ M- [1 v, ^6 e<P ><FONT face="Times New Roman">              {</FONT></P>
8 d% o! U8 H% T" _$ f<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
7 w; i) m8 O+ S7 b0 a: |<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
9 s5 V' {3 l4 X: i0 o<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
( l/ X1 ^( ]8 z3 R: X. J<P ><FONT face="Times New Roman">}//while</FONT></P># ~0 N1 F  D3 _
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
& ^7 i; r/ K" q. d& f- i' D<P ><FONT face="Times New Roman">}//if</FONT></P>1 {  o! P. h# q9 W" J
<P ><FONT face="Times New Roman">return –1;</FONT></P>
2 ~* J# f! |2 R0 G' ]5 Y<P ><FONT face="Times New Roman">}</FONT></P>  r; b5 G: Y2 X. z: R- H, [: J& y0 X
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: q% q0 M, K* t<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
' L' j2 G; p3 J  E9 L<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>  L( a( R( \/ I" Z5 K& ?
<P ><FONT face="Times New Roman">{</FONT></P>6 ^6 S$ z' [* f: _
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
/ }5 t  N% d4 u<P ><FONT face="Times New Roman">              {</FONT></P>
% P# N/ G4 F: X<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
. r7 C$ c0 ?1 W% x* z2 C( F<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>6 t! N8 K. `' E' p* M
<P ><FONT face="Times New Roman">              {</FONT></P>
* q) d: C* z; U7 l4 w  H! ?<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>, V" F# r! D  G$ ~: @; `
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>6 H* _& L5 F( \( T' V* R2 ]- A
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
4 @0 r* g' B4 R; D. W  q- Q<P ><FONT face="Times New Roman">}//while</FONT></P>5 x: ^# R: _- u2 Q# Q$ S/ \; N* F
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>/ f8 h" A& a) W; ^& U
<P ><FONT face="Times New Roman">}//if</FONT></P>
$ r. T( o9 K5 _" \<P ><FONT face="Times New Roman">return –1;</FONT></P>
% p$ i9 x! y4 \. C9 v+ W<P ><FONT face="Times New Roman">}</FONT></P>& D2 T$ ^  }$ _6 m
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 k' w# J3 {' V" R* R6 k
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>7 I: y$ f' J7 k7 z8 R
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
' R" f9 t0 E* a0 z1 R- A4 x<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>( x3 l6 X' C% Y* N/ g
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
% x5 w# J$ Q( p: m$ L<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>/ B+ o. Q  j% I. l! E
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>! @6 z3 G' n& |8 R# }- l( w
<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>6 ^3 B0 d+ P! p5 p8 ?- c+ Z- i) s
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
+ j2 [2 w! U# B% C+ C1 e& ]+ ~- f<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>% F$ N6 @. ?1 E' p6 C
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>0 R0 N  a3 z9 d! A7 ]* j. 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>/ G) e2 |$ Y% c0 w( `( P8 g
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>: p$ |* b5 d0 \" A( n4 V$ u* v  s
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
& |  P  H* m+ V, q7 c3 ^. h# W: ]<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>
# a$ x+ f9 }' c& t9 |4 e<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>6 i6 c% @; n0 m) I# }7 X
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>% J  P" ~2 N$ U2 G
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
/ h! T2 K; B- t8 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>$ T8 ~7 t* e0 a
<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>9 k+ q! w- W# f- p; O
<P >即:middle &gt; left成立。<o:p></o:p></P>
4 `9 S3 Q) \# R9 c' g. Q5 F/ }6 H( H<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
( g. i% X3 i/ v' m" g5 z<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
1 X6 E6 H( g6 w6 y3 D<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>' \5 B9 U( H- K: _
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
% t7 I0 Q( r$ J<P >∴返回结果正确。<o:p></o:p></P>
! J" Y6 O: h1 |% o6 z# B<P >(6)算法6是错误的。<o:p></o:p></P>
% a# _8 F5 z; r: B4 a4 {+ o* h* W$ \<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
8 b) `8 {6 \% \# Z1 V4 ?9 ~<P >left = middle + 1;<o:p></o:p></P>. ]) g1 y% o, _9 t: v
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>, Z) u7 z0 i7 L! [; }
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
8 p) F: n2 u, o& g/ `6 K! O<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
. a( V5 j: d" h: \6 P# p<P >(7)算法7是错误的。<o:p></o:p></P>( L5 h# Y- }' @! P
<P >在循环过程中,一旦出现<o:p></o:p></P>4 Q3 I0 T9 E$ T* E
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>5 U* U: Z! F$ G3 e* {) i$ n9 R
<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, 2025-12-29 12:49 , Processed in 1.165822 second(s), 51 queries .

回顶部