QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2790|回复: 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>
7 q8 I7 ~$ l0 p* k- c# x9 {< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
3 F2 C/ |+ a9 a4 n3 L$ b< ><FONT face="Times New Roman">{</FONT></P>
% d: a6 l# J5 h4 r- ]< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
# Z" }2 F' H8 ~4 }3 T: U< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
6 ~  ]' u# q* r8 L< ><FONT face="Times New Roman">{</FONT></P>: j" P: _' u, d" N* b
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>: P; n& h6 O3 C+ z/ ]
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
# S# ~4 B5 q6 F( `7 Y' G< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>: N' K. n; p! r) q7 q- T5 _- h
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
# X! r! @# q9 S0 G$ O< ><FONT face="Times New Roman">}//while</FONT></P>
* a" |( t, g0 i3 _( M< ><FONT face="Times New Roman">return –1;</FONT></P>
" R. ^7 d) [0 t& R< ><FONT face="Times New Roman">}</FONT></P>! t) S/ l$ t* T/ G( l  [8 Q* T3 k# o
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ N5 W: D. |" I# k" u
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* U$ O' ~- n+ c& }4 `
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
' _0 c' f! L) v  v* S# ?, [9 i3 C5 F< ><FONT face="Times New Roman">{</FONT></P>( ^% z% T; v2 v- Q5 a
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
) }# A! B" D- V4 ~- x1 f6 n/ B< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>$ V6 G2 v' d" c
< ><FONT face="Times New Roman">{</FONT></P>
$ y4 e4 M7 A6 O4 C3 W( |# \$ s< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
7 S7 {" N) ^7 S3 b; K$ u< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
9 |7 I. S' X3 n< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
$ q& @  X& ?$ E! F, y. Y< ><FONT face="Times New Roman">}//while</FONT></P>+ R  C6 |3 n+ |
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>6 D# x6 Y$ @" k( i$ z; j5 H
< ><FONT face="Times New Roman">else return –1;</FONT></P>" o4 A0 J$ Q* y9 _
< ><FONT face="Times New Roman">}</FONT></P>
( M: X+ p0 {0 c8 x2 s) C< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P># X$ R( T( ~3 M
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>6 f7 b1 R. O7 a' }2 C3 ?% x
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
, c: N# U, \2 I2 L2 |5 G2 Y<P ><FONT face="Times New Roman">{</FONT></P>
( t7 u$ d. k4 d- a+ W; `2 @<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
; w% g6 T% {; f- \<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
" a) N  _8 s/ U% k<P ><FONT face="Times New Roman">{</FONT></P>
; C; J2 J# S6 a  \) y$ D& S<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
( A( }* G0 t: B2 C% N+ F<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>" K' t  B# [  O  B2 b4 w
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>. I  S7 U$ R+ P& V6 I3 N# u, Q0 w/ ~" p
<P ><FONT face="Times New Roman">}//while</FONT></P>+ z8 G5 }5 \) a+ p6 e) c% O2 o
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- d* @; s0 T0 c  k' j# }9 q7 q
<P ><FONT face="Times New Roman">else return –1;</FONT></P>) N3 F5 j# X8 u( D8 ?
<P ><FONT face="Times New Roman">}</FONT></P>- O: o  ^$ H& e4 I# Z
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>" y: v0 m$ a: B# @! J: s
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
3 b6 p; c+ u* S: V1 O% d- e<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>/ w, g2 F, f: ?4 m5 a, |
<P ><FONT face="Times New Roman">{</FONT></P>. H' r; X3 a7 U
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>4 f% s9 ]7 Q8 o3 l* j' o+ p
<P ><FONT face="Times New Roman">              {</FONT></P>" y! I. N7 @# |6 }
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
; K$ V. K# V: S* d% O5 v* Q<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
4 A; O- g: v$ g! G<P ><FONT face="Times New Roman">              {</FONT></P>
; U6 b( W  |' `0 O/ C1 ^<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
7 r( ~' b% U7 ]! \7 l$ J/ V( [<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>% H+ P" c/ b% S3 j: v( E" i! Z
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>) p* f8 f( d- c' N1 D1 T
<P ><FONT face="Times New Roman">}//while</FONT></P>
4 Y4 W1 G4 K. w+ e; @% Q<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
. g9 g( g# `/ d: i) ?1 R<P ><FONT face="Times New Roman">}//if</FONT></P>
; l9 e' t8 e" k# ~' Z: F<P ><FONT face="Times New Roman">return –1;</FONT></P>
1 z9 ]1 F% F/ K. ^& J<P ><FONT face="Times New Roman">}</FONT></P>- t+ Q7 {# R- u- c4 T
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 ]7 w8 B; X; B! x4 f<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
8 _) W& G* E8 N  C4 g3 W) ]( |<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
. e0 n4 k, O: }1 e5 L& n. k<P ><FONT face="Times New Roman">{</FONT></P>
0 N- U9 @: b  p+ x<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
9 B2 N: |8 a- u3 D  \<P ><FONT face="Times New Roman">              {</FONT></P>
! j# L3 p  W0 k( V: Q% F0 T3 k' H<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
$ I, H# p4 E( @8 z2 j<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
  ?3 R, l: b8 i% Q/ m. `6 a5 Y, i; W. R<P ><FONT face="Times New Roman">              {</FONT></P>1 n6 y% a4 D5 t
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>+ E0 j5 |( u$ I  D) A
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
: P% h3 i- _: b. J% N# h# K, x<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
; ]4 c: q6 z1 e+ w; R<P ><FONT face="Times New Roman">}//while</FONT></P>9 W' }# c- i$ h3 g9 k- A
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>/ k& G! I9 S1 O: R5 \6 {! d1 q
<P ><FONT face="Times New Roman">}//if</FONT></P>: a' Y+ Y6 |. ?3 ?8 l( z" ^
<P ><FONT face="Times New Roman">return –1;</FONT></P>! `7 H, l( l+ z6 X
<P ><FONT face="Times New Roman">}</FONT></P>
# K4 ?+ Z8 Y& W9 G<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) q5 b$ w  K5 M9 d5 b$ ?" a
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  I% P; }# Z$ _5 b3 C<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
7 f; O1 q. P2 z4 M; k2 J, _<P ><FONT face="Times New Roman">{</FONT></P>, n6 E. O0 X9 [8 D, U
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
, d, H7 F& x& A: N6 g<P ><FONT face="Times New Roman">              {</FONT></P>
! N7 X% I; `7 v  l<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
1 @/ s$ ^+ e& i<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>* c; R. J4 P6 Q! M8 N8 h! |
<P ><FONT face="Times New Roman">              {</FONT></P>
- T" U  f8 P' L2 N/ V<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
' [2 z% r# ~, x" x0 f. {6 }9 I<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>2 u3 X8 \' D4 M/ E6 {9 J, d
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>0 ?* Y6 v/ X5 O2 v- ~9 g
<P ><FONT face="Times New Roman">}//while</FONT></P>5 \/ b- R% H; l. T, R6 Z$ G
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
+ @, ?+ x3 ^1 f4 ]1 P/ z<P ><FONT face="Times New Roman">}//if</FONT></P>
8 e+ c: W5 P9 c* E. h; H5 L7 D6 A) O<P ><FONT face="Times New Roman">return –1;</FONT></P>8 ?) a; k% M, g6 n
<P ><FONT face="Times New Roman">}</FONT></P>
' p$ B% r! n1 t- R, e$ H<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>! I, J/ c! }% \1 f
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, E1 N4 ~* [) z  W* t<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>! s# P& X+ N6 s. n
<P ><FONT face="Times New Roman">{</FONT></P>
! m4 K/ V9 h0 i<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
9 L  q3 Z* D5 F6 o2 C0 b& V; ^0 K<P ><FONT face="Times New Roman">              {</FONT></P>
+ [- ~! x/ R& R' T<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>5 v' G9 S: @, ]) v4 _" r
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>5 v$ ]  K1 C' E
<P ><FONT face="Times New Roman">              {</FONT></P>' \# Q% j8 r; e7 B1 z
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>5 x' t, x5 V8 F9 M$ D
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>1 F; x& x9 d, M* x8 B
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
. y# |$ e% @9 F<P ><FONT face="Times New Roman">}//while</FONT></P>- k' l$ e' G' f+ {' y; M
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
1 d  k+ H- U8 D: m9 u* i<P ><FONT face="Times New Roman">}//if</FONT></P>9 S* D# Z! P+ k
<P ><FONT face="Times New Roman">return –1;</FONT></P>2 n3 F2 H- |! \' }9 W
<P ><FONT face="Times New Roman">}</FONT></P>
% {% K  W. N9 k! _7 B7 W<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% B  ^& z! j; c! [: d6 ~
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
" G. F. \& h$ h$ k* R<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>' z% Z; f$ v+ r5 X
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>2 i: I* N8 T  ]/ k, I
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
; B' [; Z# z4 e3 o) ^' p<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
$ p* ~+ ~3 S; b; z1 T: `, S<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
% l" j4 ?; C3 q3 |( L7 M* ]* {$ r2 a<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>- z* K! m: b0 l" |, \
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
# v% c0 U5 C* G, U<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>9 o7 L! f+ S! F7 S
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
* n6 D, g" Z) N4 Q<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>- ^- D3 i3 k! `" T  ?( X
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>5 R! o* W) C: d% T7 D
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>/ q3 z1 l7 Q& C* _
<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>
. I, h+ I! q- P; `2 G<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>6 m) p" J# n# M
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>" ]' {) z+ N3 M3 l0 |( [
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>2 f1 W0 W7 S8 u9 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>
+ `: w5 [- |- c- J7 Y: G' E<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>, y1 @( f2 d1 J$ n: K  k$ ]! A/ h+ }
<P >即:middle &gt; left成立。<o:p></o:p></P>
" a  {! G& ?4 q- X<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>( Q# n4 x% Y0 A" z
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
! v( u. r7 S  H2 v4 ]& i<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
' b+ C( d. R2 I% {& [; h2 B4 S<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>+ w% |/ D4 z$ ]: w& _) r2 ?# U; q
<P >∴返回结果正确。<o:p></o:p></P>7 G. W4 t7 s$ R
<P >(6)算法6是错误的。<o:p></o:p></P>% @% [: j- o2 h8 n# g  J' y. c
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>( A3 i' R( u. Q" D3 \5 g
<P >left = middle + 1;<o:p></o:p></P>
' {4 q0 y& C3 c3 N% s6 z<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
7 U& C" z( a' R' m* _4 B& Z<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
/ R6 }3 B  r3 v$ Z0 `& w8 ?<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>. I' J5 t+ r& S: ]3 b7 u7 H1 o
<P >(7)算法7是错误的。<o:p></o:p></P>: ~7 w" m% r) @
<P >在循环过程中,一旦出现<o:p></o:p></P>
7 d* `9 h" T7 A- M3 k<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
9 n4 R/ [; G; A+ T& M2 G- p0 l<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-4-20 03:33 , Processed in 0.445346 second(s), 51 queries .

回顶部