QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2813|回复: 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>
) ]3 x0 V' @' S7 |  q< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
: r) p* |- d: u4 Y+ J( F- o< ><FONT face="Times New Roman">{</FONT></P>* Y6 l5 u1 o) s! C5 X. ?+ w/ M
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
- w% u0 X4 T& r0 U' G1 x$ @: v* K< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
1 |  Y6 n& J% m) v  J# X< ><FONT face="Times New Roman">{</FONT></P>
/ _1 X1 M% B% k: q3 Z7 `8 T7 R< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
) o, t$ f/ _- N3 W: J4 G< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>8 Z3 C  M  i5 d: v: b
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
( y8 B$ G$ P* o; N* [6 n< ><FONT face="Times New Roman">   else right = middle;</FONT></P>1 j3 d6 f- a: e7 P
< ><FONT face="Times New Roman">}//while</FONT></P>' U4 o* J6 d' P5 F2 d: U, _8 L2 A; ~
< ><FONT face="Times New Roman">return –1;</FONT></P>
) _. r* z9 J/ ]- ^/ i) z+ A< ><FONT face="Times New Roman">}</FONT></P>
+ q' j1 U9 @$ ~< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>: q) ?1 A7 _* D( N& a
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>7 a- f- L9 r8 A
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>+ g( }' w* n6 q2 T6 N
< ><FONT face="Times New Roman">{</FONT></P>
# |& n3 \- d. m& `) ^9 S< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
6 c% E, s0 d& }7 f" M! B< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
2 c# M& Y" K' ^+ m" m3 K: }- C) _< ><FONT face="Times New Roman">{</FONT></P>. P; h6 `. r; b* V
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>2 f0 j+ j, l) A5 z; Q" U% \
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>: w4 n# H  A. L
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
5 Z& q6 d0 D+ P; s( _* g< ><FONT face="Times New Roman">}//while</FONT></P>
* Q1 U2 B/ u/ G< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>$ e" @/ M/ X1 b& m
< ><FONT face="Times New Roman">else return –1;</FONT></P>: |5 w+ L  C# @5 v0 h
< ><FONT face="Times New Roman">}</FONT></P>4 `* j2 m6 M3 Y5 D" d, E: a
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
& v3 n& ]. g3 G4 A1 N$ B< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( s( G% H( A( P. i; Z4 Y( `  g, n
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>( R4 o$ B. b6 I5 d
<P ><FONT face="Times New Roman">{</FONT></P>+ N9 D( D5 w' d. D) c3 k9 S
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
: E- N+ B! r) N, q$ G<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>7 ^: G$ q4 N7 i. \. ]
<P ><FONT face="Times New Roman">{</FONT></P>
. e9 ^5 h# ~. o2 O# M8 Y5 B6 u7 v: A<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
1 w0 U, X& E8 U; {# a<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
8 Z$ S  T4 b7 g( `) C<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
( b/ ^1 K% D+ ^3 G; n% w$ O<P ><FONT face="Times New Roman">}//while</FONT></P>
# F# W8 C  x) w<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>: L1 T/ p$ k% M! `" ?, G
<P ><FONT face="Times New Roman">else return –1;</FONT></P>2 X* I5 R* x( _8 h' |
<P ><FONT face="Times New Roman">}</FONT></P>. g0 y# y0 n, O, r% O
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( _( a) I' U% x7 I
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% J. ^( s3 ?6 K# k
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
& ^" J# j4 i2 i: S# \! L<P ><FONT face="Times New Roman">{</FONT></P>3 S) @. t4 v2 d. X/ G7 _' i( u& N0 a3 t
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
" P# m7 _( J5 x3 f5 n<P ><FONT face="Times New Roman">              {</FONT></P>
. _& j+ Z0 O+ }: o* g<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
, a" T# R7 F+ V% E* Y) q- F+ v<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
% U& a8 w/ D& p2 a  K' L<P ><FONT face="Times New Roman">              {</FONT></P>
& q5 @- w- Y5 _, h<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
8 U. g' X! A3 {+ V8 F2 c<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>6 y, q8 K1 q: M' D; k* `8 Y
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
; A* F; Z# G$ H<P ><FONT face="Times New Roman">}//while</FONT></P>
3 b* X* g; `# t7 X! U# l  |* \* M<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>. }( h6 `3 Y. [& a2 N) P
<P ><FONT face="Times New Roman">}//if</FONT></P># z& \6 K  h7 d+ \0 P2 |3 l
<P ><FONT face="Times New Roman">return –1;</FONT></P>* x3 y6 p, e. t+ }
<P ><FONT face="Times New Roman">}</FONT></P>. _5 d/ B' E2 W* g
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>7 R6 m  B& G' k& r( b' ]
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  ]" f0 u- B" M  e, L+ h, o1 v<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>6 u9 g" l$ p  u' x- V/ s4 }1 Y2 T
<P ><FONT face="Times New Roman">{</FONT></P>
- d3 ]' `8 p/ q. C8 {, w<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>( P, J$ ?  y1 d" u' c
<P ><FONT face="Times New Roman">              {</FONT></P>; h2 G  S, I2 H# b, L
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>% j9 g& i) Y% z6 p$ ~' ?" S2 r
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
3 B* m# s4 z( }1 H<P ><FONT face="Times New Roman">              {</FONT></P>4 {7 E4 H+ G6 R3 H8 e' C
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>5 n1 ]/ t' X1 H% G, U
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>! n! W4 Z; N' t: O& S; C  k
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
: p& n2 k1 p* o4 o' o: |" O<P ><FONT face="Times New Roman">}//while</FONT></P>
+ x: o& k7 c# _$ R  e8 {<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>$ |" F8 E, T- n% W+ B& c
<P ><FONT face="Times New Roman">}//if</FONT></P>* }* ~/ W2 L& n. \
<P ><FONT face="Times New Roman">return –1;</FONT></P>
- {  c  w7 G% ]3 _+ g( h. z<P ><FONT face="Times New Roman">}</FONT></P>3 Z# [; u: S# F" E
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>" `0 f; c6 I, V) Z5 w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
, N# h% j5 q4 N) [+ }* s) _% Y<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>; u. M1 O7 Z7 J6 U! `& s
<P ><FONT face="Times New Roman">{</FONT></P>
* A) `% a' U9 x: M0 d# R; D% p<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
) x# k( @* N: [& K* D. p) F<P ><FONT face="Times New Roman">              {</FONT></P>/ m4 d) T- s7 @3 A, C4 D
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>& w; I; B& @( D  ?, ^& F
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
! g# g! W# D. Z1 F$ i# f<P ><FONT face="Times New Roman">              {</FONT></P>6 v3 b" h: K; ], p; p2 |
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>( k  X$ S' i/ Y0 ?: v6 _
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>) }5 C, [5 S$ j. f7 {9 N; V
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>  J: v5 }, S$ E/ e. K7 V- k
<P ><FONT face="Times New Roman">}//while</FONT></P>  G* ]/ l( M. i* m) p7 ^
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>* Z! c; f; @0 H  X, m$ X
<P ><FONT face="Times New Roman">}//if</FONT></P>9 L4 u( L% M3 C& m* ^  `' I
<P ><FONT face="Times New Roman">return –1;</FONT></P>
! x; h. \8 F5 N; E<P ><FONT face="Times New Roman">}</FONT></P>: U" O: p4 N* B% y0 \" D' w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>. g; v+ q6 ^! O8 \" ?
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
( I  |% G3 d% Z+ }5 n/ c$ c0 V<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>" ?$ L1 \! c  ~* p- p7 a
<P ><FONT face="Times New Roman">{</FONT></P>  F9 Y6 e5 [! t$ V& z% D/ d# d# v4 b
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
+ ~# Z" W* R7 Q<P ><FONT face="Times New Roman">              {</FONT></P>. B/ y' n# G7 ~: ?
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>5 Y* B* b1 Z7 A6 \+ B% d. }
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>9 h( U# e/ R1 B; H# @; I* N; w& X7 M
<P ><FONT face="Times New Roman">              {</FONT></P>' p* _! H1 x" r0 v
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>; r- P, e  M) t" r5 d, Z& O- u
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
( g6 ~: b1 z4 F+ D$ J; y, _+ B" C<P ><FONT face="Times New Roman">else left = middle;</FONT></P>% n; ]5 H( F7 i. k/ n
<P ><FONT face="Times New Roman">}//while</FONT></P>
9 C8 s3 E5 k6 p8 l* Y* S/ r4 C  g5 X<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
* [9 \# ^3 L2 v# `<P ><FONT face="Times New Roman">}//if</FONT></P>
$ N( u8 X! y. [: z/ o' |<P ><FONT face="Times New Roman">return –1;</FONT></P>' S0 l2 @. }. q' V1 ]
<P ><FONT face="Times New Roman">}</FONT></P>
/ o+ o1 z7 u. \, D<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
8 s1 ?( ~$ l1 g+ R- T0 M, G- M* h( j<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>- `8 g& }9 v; c+ h: r. [) E# t
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>2 a9 Q; P8 H1 F! t
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
0 @/ f$ l8 r0 H) @! r/ o- l9 h" B<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
  _9 c, e3 E, A* n: a<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>; u9 X' K' V9 N! x% D( n
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>( C7 V5 F5 ^! X. `
<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>
& Q& C1 m5 `2 B5 g7 X! V7 q2 J6 v<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>% k# x5 b' H/ M- b& w3 N6 V
<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>/ V. K$ ?6 n, Z8 n2 \
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
+ D1 t6 }7 y% o+ @<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>' |. a& j. B9 y6 m
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
& _0 q0 b/ I  Y  l& O# A3 i6 X<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>) F) t, ]: ^' [/ s* _( ?3 P8 P
<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>
' ]1 n  S8 p3 C  Q<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
- m4 l6 G$ c' p( p7 n( P& `; x<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>. T% L2 U( {, W) g, y
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
& a6 ^7 @0 \3 N: C: M7 g. u<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>. v1 r7 u; l0 G% `$ |# W
<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>. g) F& t) y- Y0 }& A: O: ~( m
<P >即:middle &gt; left成立。<o:p></o:p></P>+ f1 y0 s$ K# i( q) @
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
, n& r" V0 N+ e0 e2 M6 d<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>& Y) y1 i; z; `2 X6 ?
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>2 o) T$ O# j; u" J
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
- ^! f* ~6 D% J7 J0 b* }<P >∴返回结果正确。<o:p></o:p></P>
/ r. P; S) M/ \* p! M<P >(6)算法6是错误的。<o:p></o:p></P>
: R" P4 _3 D; F/ U: X<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>, L) T) \4 `9 C5 M- ^7 ]- U
<P >left = middle + 1;<o:p></o:p></P>+ B: u0 s& G2 X* O, l# g. t! w
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>9 K' v3 k) M( H- G% K
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
4 P1 i( i& _9 e<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>( p. L5 s& @: u- K: N; H
<P >(7)算法7是错误的。<o:p></o:p></P>
% K, R: R4 g1 O. ?* n% e" l2 r<P >在循环过程中,一旦出现<o:p></o:p></P>
) M- H+ V* }! G! L# N2 O" [" L9 M<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>0 W: c3 d# F% T) j, K# c
<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-6-4 08:35 , Processed in 0.500262 second(s), 51 queries .

回顶部