QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2899|回复: 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 l+ Z8 [3 o6 l+ C  G# Y0 T
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
5 v* t8 I0 K$ ?4 l! a7 b+ Y. E< ><FONT face="Times New Roman">{</FONT></P>
( y7 n3 Q' k( C6 A0 a5 y< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
1 O* T3 p* J" J; A! \< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>3 f" s1 Q1 z# @8 L; @
< ><FONT face="Times New Roman">{</FONT></P>4 ~7 S% g, J& F4 p
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
" S  `4 O( y0 Q, d& ]  m8 e< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
0 H- f  T" O: K7 X$ }< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>' Z6 s) K& Q' a' u+ z& v5 l' S
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>9 a- g4 Q; ~/ j6 c; F5 M3 c. f2 I
< ><FONT face="Times New Roman">}//while</FONT></P>
# u  }3 x6 z. C. n5 {0 a& C< ><FONT face="Times New Roman">return –1;</FONT></P>- E( D7 k& V: ]/ z' ^
< ><FONT face="Times New Roman">}</FONT></P>$ _5 u# }6 b7 \8 T/ z5 p& `' t
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ e" ]8 W/ ?/ k( J+ x& O4 ~
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( S  c5 K* q9 p
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>' M5 A* t! p  m6 @
< ><FONT face="Times New Roman">{</FONT></P>- `0 I. Z1 o" N9 ^/ R
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
, I/ O8 F1 ]& j3 t, d1 f; B# s< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
7 `8 Y9 [* Y* t. Y6 v8 r: p< ><FONT face="Times New Roman">{</FONT></P>1 F0 Q# C! K) P% s: I+ t
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>- s- F0 F+ r  R7 N0 K
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
. |1 L5 }0 s6 [& z- w( a9 q< ><FONT face="Times New Roman">   else left = middle;</FONT></P>; d0 m0 v0 a" V% P8 e) O
< ><FONT face="Times New Roman">}//while</FONT></P>
! {8 o! _" }  V; L, ]$ I1 c7 |( M< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>1 |+ g& Z9 l3 N+ s
< ><FONT face="Times New Roman">else return –1;</FONT></P>
! N6 _1 u* \3 c< ><FONT face="Times New Roman">}</FONT></P>' z' i0 E$ G/ z, ]
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% W" {4 r; H9 v* c7 H
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" K6 T9 i! v0 A< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>4 X5 \( O  }/ V  e4 E' q! a; F
<P ><FONT face="Times New Roman">{</FONT></P>. b2 \9 `/ P: N- j: _5 p
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>3 E% p$ p0 S3 m
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>- m8 V1 D; d+ D4 R9 c9 n
<P ><FONT face="Times New Roman">{</FONT></P>
% d0 E& x) H- c" {) d<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
8 ?8 h% q6 |6 j3 v<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>$ A$ W" M& m( r9 \, W
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
/ X8 G& F( D; s7 A5 n# O, |% {6 C; L, x<P ><FONT face="Times New Roman">}//while</FONT></P>9 ?. d0 `1 A" H: N/ A
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
# R6 Q/ q5 G- y7 j<P ><FONT face="Times New Roman">else return –1;</FONT></P>
* q6 N9 A" Z8 P7 P9 a, u) R<P ><FONT face="Times New Roman">}</FONT></P># Q; y: b/ M+ S9 Z- K6 ~
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- Y- c  L. a7 P
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
6 |" t7 i3 N- Y<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
7 k; ?  @! g0 Z& y, P2 l<P ><FONT face="Times New Roman">{</FONT></P>
% d5 ?- l5 @; `, q0 s<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
% [9 |3 @* L6 M  H  g' v( n<P ><FONT face="Times New Roman">              {</FONT></P>
1 C3 f  o0 r; w/ q! i<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
9 V" r; O1 z6 q<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>( M8 l. v3 L* n; p5 h
<P ><FONT face="Times New Roman">              {</FONT></P>
9 O" r. X) E& R* t  w' c<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
2 r- L9 C/ w1 l" `0 i<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>1 H/ ]) P; K/ u/ Q2 F
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>* Q/ N6 ~( M; v
<P ><FONT face="Times New Roman">}//while</FONT></P>
8 p6 q9 i" Q. U0 i/ N% d" m<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>3 A! A/ z: s/ i
<P ><FONT face="Times New Roman">}//if</FONT></P>8 D' q1 E7 W* b! e6 o# h; F
<P ><FONT face="Times New Roman">return –1;</FONT></P>
5 F( c& o) M6 y) B9 [0 v8 k5 Y<P ><FONT face="Times New Roman">}</FONT></P>, F# y0 b5 t) j: g9 P- [
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: M; Y, l+ Y% c0 j% y<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
2 s9 u' `- ^' h" s2 H9 B  n2 S6 l<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
" ]- x4 t; s8 p* M% b) Y<P ><FONT face="Times New Roman">{</FONT></P>% n$ V) {8 q2 l2 r) u; R' D
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
( |3 Q) b9 |7 b<P ><FONT face="Times New Roman">              {</FONT></P>+ s: v! [% |* w: X; k
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
5 d  F* Q" B5 `" h% s; u<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
# S5 Z" \) L8 n# U! `<P ><FONT face="Times New Roman">              {</FONT></P>* W" n- f0 I/ G/ I( P  X0 [  Q
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
$ r1 A8 P' ]- g6 a<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>& {0 l; X0 P$ `- n( f% Y7 m  D
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
& ?  O  ]& m# x+ ^<P ><FONT face="Times New Roman">}//while</FONT></P>4 H5 `( K+ M- a3 O& u9 m+ U* N, G
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>* c8 Y4 W. P% _% G
<P ><FONT face="Times New Roman">}//if</FONT></P>1 [3 x7 v' @7 Q5 e
<P ><FONT face="Times New Roman">return –1;</FONT></P>
$ q( y1 \/ }3 z  W6 g3 D7 W" p<P ><FONT face="Times New Roman">}</FONT></P>; B6 q1 H4 I& d2 u' }4 m
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) r" O! J0 [1 E2 V' u) ^/ Y+ I
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>; r* e! l. p4 m- k
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
3 t" Z8 ~2 H' R1 E; K' U<P ><FONT face="Times New Roman">{</FONT></P>1 z& y& Q5 X4 `- J$ f+ t! V
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
; V1 o% Y5 }2 F, T8 C# L<P ><FONT face="Times New Roman">              {</FONT></P>: U! P" B& S) ~7 V, r
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
3 _1 k9 ~/ D0 b0 X- j: G: F<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>" L! G1 N5 z- s' \1 m4 @/ c+ n+ l5 |
<P ><FONT face="Times New Roman">              {</FONT></P>
7 X! v* l2 H1 j, K3 n1 |<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>7 ?% I( s! E& |' u" a
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
2 I" v$ M* \8 Q5 X<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
7 W9 `% w2 F2 S<P ><FONT face="Times New Roman">}//while</FONT></P>$ e) m$ ]  ?% E- w" O' c# A% `6 N
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
+ I8 B( @( m) ?5 s+ U4 ^! u$ k  w8 ]<P ><FONT face="Times New Roman">}//if</FONT></P>% l( m' B* Y3 p. f5 V( B
<P ><FONT face="Times New Roman">return –1;</FONT></P>
- y9 l' V& u5 y) ?2 \0 a<P ><FONT face="Times New Roman">}</FONT></P>
* [8 Z  K. d& T/ i" n# O<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>3 p5 f9 N0 }7 U- O7 u& J' P: A: T
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
# ?# |( b8 p% x, m<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>( }) N6 J9 Z! s3 ]0 Z" u/ n6 E+ |
<P ><FONT face="Times New Roman">{</FONT></P>
- y5 H0 q4 H- c<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>* O5 c0 Q! r( s& p, `& L( b0 {
<P ><FONT face="Times New Roman">              {</FONT></P>
; i# Z/ n- p4 X! A<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
4 H6 ^/ U0 G: }2 X4 v9 i0 r<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
  d& j7 F# R4 K% Z- l<P ><FONT face="Times New Roman">              {</FONT></P>3 _, x! w1 i1 \! ~! T
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
- p+ k0 F" j& e  d' x$ {<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
; f& a, B5 T: q<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
! u" E8 B- S) W/ [4 d5 g- ^' G<P ><FONT face="Times New Roman">}//while</FONT></P>- c, p/ s& v. D
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
: n3 k) V8 h( s5 W<P ><FONT face="Times New Roman">}//if</FONT></P>1 k4 \$ M' a: Y) q: b" O& d* a
<P ><FONT face="Times New Roman">return –1;</FONT></P>: d. ^. r& X3 m5 O
<P ><FONT face="Times New Roman">}</FONT></P>
* ?  a7 _/ h/ y6 Q! ^: ?) R<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
) s) v0 V- z& {. t, N<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>6 K% D2 S7 ~- R; U
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
( B! v, s1 I6 @$ |+ [: T1 y" h9 R/ d<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>/ w0 L% T2 u: I$ u1 P$ f5 I
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
# D- C; d) v, e+ ~  e<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>" U/ N6 C! k" u3 ^6 ?% m0 P
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
1 b( E# p1 B1 u8 g- N6 ]0 a- B8 W# 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>
3 m! _/ I7 Z; Y" E<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
7 l' O/ Y0 Q) F' B- C. ]<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>
, y2 J. ~! }/ N. F. R<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>( T% b! P# X6 m" n& _
<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>
9 ?% t( Y  u# k! r# `) T% J: n<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>' ]2 Z! b6 Y. R
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>3 Y& w& \* I9 \$ D9 L; u
<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>
3 k/ Q' P* N) c$ l& j% E& y<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>2 L  i% s3 u# D. G% H$ d  B2 |# z+ }2 Q
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>; ^; q  K( ~# {
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>+ Z! W. I2 d: t! M' q3 V8 M! o4 ]
<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>
3 o% h' e- b7 ~4 C% `<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>
  l: e; O( H: I5 e<P >即:middle &gt; left成立。<o:p></o:p></P>& H4 _0 p) V6 I8 x6 G9 I5 M
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>6 N/ V: o7 X9 Y1 M
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>1 Q  I/ L: E% I
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
5 [0 a9 i0 f9 \1 c0 n& I( [" @<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
# t6 H* l& s3 [; C6 C9 d2 s<P >∴返回结果正确。<o:p></o:p></P>
; P0 ?9 {2 M, M0 a% H<P >(6)算法6是错误的。<o:p></o:p></P>
" E+ W, [* v* s5 T<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>8 g( t- v" Q4 x3 g
<P >left = middle + 1;<o:p></o:p></P>
) S: a# l# _7 s6 a6 m' z<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>& }5 ]+ y7 `+ Y9 s3 a/ Z
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>7 l& E/ `( U3 p, l5 M8 s" Y( d) b- {
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>5 M0 G7 ^! {/ K4 M" a* b9 k
<P >(7)算法7是错误的。<o:p></o:p></P>% R8 m9 Z. z% P" K, b/ x* N3 t" s
<P >在循环过程中,一旦出现<o:p></o:p></P>
% Z8 s# i9 g/ G1 I<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
& W& R+ w+ Y2 S9 ?. D* ~<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-24 10:17 , Processed in 2.574791 second(s), 52 queries .

回顶部