QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2795|回复: 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>
/ z& T8 _6 `" E: s! ~' X# N% _; ~< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>9 {9 l* `, n7 e5 ?
< ><FONT face="Times New Roman">{</FONT></P>/ j2 {+ o) z# _% g! w8 n
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
# o* t9 _" k" |$ Q) u  ~< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>+ I3 n, M$ U' g# _' L
< ><FONT face="Times New Roman">{</FONT></P>1 P% N: J  T3 p0 H* {
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>, T' p; h- n: l0 k
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>, A/ C8 c% G9 y  e, j, m4 T
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
3 |4 _0 K2 R; x. ^  T3 s< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
5 C: w, j& @  o: R( j! `( c0 z9 X< ><FONT face="Times New Roman">}//while</FONT></P>, F$ w& }* r. U! `( y
< ><FONT face="Times New Roman">return –1;</FONT></P>
- Z, v( q$ ^  Z  n< ><FONT face="Times New Roman">}</FONT></P>' O& M: M; W( j! o
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P># v$ D/ O* @. F3 z9 ^
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
) q& r  |+ p) l/ N< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
8 Z( B( r8 e: Y, K0 r+ ^( H0 v< ><FONT face="Times New Roman">{</FONT></P>, p6 _  ^$ Q* I
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
& m" L; s6 A" e8 Y5 ]0 E# x1 ~: Y8 f< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>6 u, C% l8 U1 R
< ><FONT face="Times New Roman">{</FONT></P>2 [4 y' d, g, ?# Z, |. I
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
4 J, s  @  ^0 }6 a( w# X< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
# J# }: P5 C* q+ J< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
& h; D( F8 ^9 x7 V6 K; B+ `. R< ><FONT face="Times New Roman">}//while</FONT></P>
" f. z( Z% b. }4 |< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>% x9 I; M6 A% C3 {7 r' d% _0 z
< ><FONT face="Times New Roman">else return –1;</FONT></P>
' j+ W0 w. r& |1 Z< ><FONT face="Times New Roman">}</FONT></P>& \, {. z$ T3 Y; _8 ]. n
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 P# ?+ [- U" ]+ L. Y" u! t" u
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ d4 U( u; v; z3 e( Q
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>- e9 e2 |; ^  q
<P ><FONT face="Times New Roman">{</FONT></P>
0 {, R9 Q1 U. {1 S0 v) C<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>  W- g5 H0 X; ^* k- A
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>3 d% G9 `. W" y7 Z5 R
<P ><FONT face="Times New Roman">{</FONT></P>% l$ q1 b0 V3 c1 d& i0 q
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
7 v% @/ e4 o9 k$ w# g<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>& x1 e3 U; Q* m5 D* j
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
/ ^6 j9 H4 S! u<P ><FONT face="Times New Roman">}//while</FONT></P>
& L3 s/ G5 G  i, h! r<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
9 p" A3 m: b7 D# E4 m7 R+ }<P ><FONT face="Times New Roman">else return –1;</FONT></P>
# z" V7 P; t% v; g  C& k<P ><FONT face="Times New Roman">}</FONT></P>% r5 B" |% b3 B7 [. j" P5 h7 L% S
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 u+ r# ?$ K; l3 i% J0 N' v5 K
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>0 n5 i% J# A! y
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
- A9 u- E) [5 T, E) ]1 \<P ><FONT face="Times New Roman">{</FONT></P>  q& [: E! g& L/ _; B* ]7 C+ h
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
& u9 n/ r' i3 e/ a5 ]<P ><FONT face="Times New Roman">              {</FONT></P>( t3 z; Q: w. E6 ~; G% G3 [1 c$ x2 c
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>4 f# H) B3 |; b
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>8 O& P$ X( ~( [% x
<P ><FONT face="Times New Roman">              {</FONT></P>
# P- ]' _" d' q: Q<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
/ @7 o: S. K) a<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
' F0 f9 Q+ y  |<P ><FONT face="Times New Roman">else left = middle;</FONT></P>& p% E1 n. A: y  ^; ~
<P ><FONT face="Times New Roman">}//while</FONT></P>7 C: i3 p. c$ v
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
8 h- M, x0 D' {% ?9 v% C) A<P ><FONT face="Times New Roman">}//if</FONT></P>5 h3 p$ y6 N+ w  b; g
<P ><FONT face="Times New Roman">return –1;</FONT></P>; @. G, R2 f( `* F: \# S
<P ><FONT face="Times New Roman">}</FONT></P>
' u3 {) b3 {' |+ N0 s<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
' r0 d* j* ~0 c/ k<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>. I$ o, L; V) Y0 [8 u7 s. E
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
) F3 s5 d; u' [, b. f0 q0 ^<P ><FONT face="Times New Roman">{</FONT></P>
8 @" g) m# T) E) d2 u7 P& q# E<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
. ^3 i7 |1 c$ W2 ]' p<P ><FONT face="Times New Roman">              {</FONT></P>; a# B  o8 V- f1 c. Z+ X- P
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>, p+ c. o3 }# X8 D8 O: H) X2 ~
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>8 m/ t% [' Q2 r1 R* t
<P ><FONT face="Times New Roman">              {</FONT></P>
4 U7 m. z3 Z& ^% M4 T2 @4 K<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>4 n8 y! u5 Z: p( f6 M
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
* S7 j8 [0 W4 ?/ l* b2 f3 v; H, c<P ><FONT face="Times New Roman">else left = middle;</FONT></P>+ m4 `( ~6 m# k& S* l
<P ><FONT face="Times New Roman">}//while</FONT></P>
( z8 K- B/ @7 O7 M<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
2 k& V$ t9 P, h<P ><FONT face="Times New Roman">}//if</FONT></P>* t6 Q9 x, }& W" i
<P ><FONT face="Times New Roman">return –1;</FONT></P>
# r8 D" s! C& U: i* N9 C6 n<P ><FONT face="Times New Roman">}</FONT></P>6 o: ]8 X1 g' M1 U& z* y. B* o) k
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>9 ~* ?/ `* c' u8 h
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
8 d9 H- o* e7 ^+ e8 Q. v4 }( W- H% g<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
# ]3 _& Q: A4 `, G, s! [<P ><FONT face="Times New Roman">{</FONT></P>4 f  Q$ E1 B7 W% h1 Y, c: H
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
8 O" {! B3 S1 O  w6 q3 E0 E<P ><FONT face="Times New Roman">              {</FONT></P>& ]' \0 y. W( i; J, |
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
$ w0 C; A0 b% m<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>( z5 o/ r8 w4 Z; g
<P ><FONT face="Times New Roman">              {</FONT></P>( n. ^2 W1 @3 `) l! z. J9 i5 D
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
8 j6 `$ m( s8 Q$ ~$ J/ p1 }& H( W- r<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
; c& g' Y8 t2 n<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>: L! m) U* i) R7 }
<P ><FONT face="Times New Roman">}//while</FONT></P>6 C5 J% T' N9 ~' G9 a
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>1 O# _! I4 E! b  N. D+ K
<P ><FONT face="Times New Roman">}//if</FONT></P>* _. b  A: w+ i6 z1 h( _2 D1 U
<P ><FONT face="Times New Roman">return –1;</FONT></P>
' e. @% k% F% Q! a! p; K8 h2 a<P ><FONT face="Times New Roman">}</FONT></P>
$ t$ W% j# T' F" s7 }/ u, [# f<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% {) e1 I8 z/ r6 }<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>8 J  G# G7 s+ r! b8 p
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P># G( S) Z3 v. \+ f- j/ O' \; V7 U
<P ><FONT face="Times New Roman">{</FONT></P>
+ Z* [/ q8 ]' \: h6 O3 q6 p+ K& l<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>/ G( V; b1 p) C! s2 w
<P ><FONT face="Times New Roman">              {</FONT></P>( _2 x& x/ ]/ _; r  i
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
% D0 `& A0 z' ?3 H* D<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>6 r9 z# P1 x3 `; {/ Z9 f7 S$ k+ _
<P ><FONT face="Times New Roman">              {</FONT></P>
# `( R  l- @. x- j2 w+ ^<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
8 z& b. L4 }$ X( b<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>+ U: Z/ O$ L% G5 K; I
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
" j3 ]5 K6 ~5 \1 U2 Q: c<P ><FONT face="Times New Roman">}//while</FONT></P>6 X4 B+ N$ V3 ?+ S$ M2 A$ M
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
# G; ~# W& T/ o3 b<P ><FONT face="Times New Roman">}//if</FONT></P>6 y8 a9 A5 T( S- R. ]3 F6 E
<P ><FONT face="Times New Roman">return –1;</FONT></P>
+ b& d2 V/ N, M+ r0 W! t) `<P ><FONT face="Times New Roman">}</FONT></P>
% e5 Z8 l1 h) L# ^% m- e  s<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
5 U! V8 G* I" J6 O- n<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>& E9 P( q$ x  M8 v( H: k( q2 i
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
6 t2 Y+ b% a3 O# L<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>( q; [) ]7 ?$ H+ n/ o
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>2 _  j0 i# H' a3 Z% T
<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
% i9 _: V2 e8 ?- V+ I# k- ?9 b<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
& N# ?9 N7 a; ~2 ]( d: y9 v+ p<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>! W1 L# j3 B/ w" R9 P8 b# Q
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
- g1 ?; _+ ^/ G! P4 M, i<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>0 A5 C7 J% }0 {6 d- p$ v4 \
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>( Q8 j5 G9 B4 b4 T9 s4 o7 V# i
<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>. ?3 Q! p# K, {( i: j* y8 \
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>' u  j, ^. v4 n
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P># E5 Z3 q; _/ @) F" [7 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>
% A4 G- M; L* u<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
8 K. N' W7 V# R1 A1 ^+ s<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
( f' i6 s$ V0 y<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
% X, Y( ]* b& p) c<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>7 ~2 L1 B8 ~9 s+ P, l& [: X$ B5 _) 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>1 g3 V- r/ e; f( I. C0 D
<P >即:middle &gt; left成立。<o:p></o:p></P>! x+ p* `0 M4 D0 I5 V" z; _( 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/ l6 d* D; v<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
% E6 k" U! h, X! l<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>4 C* N. G+ v- G2 }2 q% T5 ]9 Q
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>2 A$ r1 w: h& _: Y
<P >∴返回结果正确。<o:p></o:p></P>; n5 \# d- L2 ^8 e' U: o/ S
<P >(6)算法6是错误的。<o:p></o:p></P>
9 A5 G* }( I; y. c<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
3 T4 {0 A6 a1 @6 j. T- P0 R0 H<P >left = middle + 1;<o:p></o:p></P>
8 B  K# D* y7 W4 q2 x9 x<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
; o6 P* Y! r! X' R% m" b- n! v<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>/ _2 V' L& y) \' r
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>- b- P5 q7 d9 E! q% _
<P >(7)算法7是错误的。<o:p></o:p></P>
9 d  Y+ v8 b! Y$ w  i0 ^4 [<P >在循环过程中,一旦出现<o:p></o:p></P>6 w7 |+ j  L8 j7 {; K2 x
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
$ E" c3 p& g2 ^+ d6 r7 M<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 17:51 , Processed in 0.421290 second(s), 52 queries .

回顶部