QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2897|回复: 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 u7 q/ l6 ^2 V2 C4 J( o< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
, r- ]: T6 k0 P< ><FONT face="Times New Roman">{</FONT></P>
/ f4 [4 Q3 l! C7 D( H  L! J< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>! I& J0 u2 l- A& Y) j) b
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>* b; J* K5 d( `6 Q/ O; M
< ><FONT face="Times New Roman">{</FONT></P>! p: r# u6 k/ ]7 ^0 t% X3 T. |
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>" }! c# u* C, v$ u) T
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
+ \# M5 X: ~5 J) a3 a< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>: {& ?) c1 |/ r% D
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
" f' {6 G  o+ q( y9 W) ~< ><FONT face="Times New Roman">}//while</FONT></P>
0 ?" _* k  K* D: y< ><FONT face="Times New Roman">return –1;</FONT></P>+ i/ H3 K3 T5 y! N3 ?+ H
< ><FONT face="Times New Roman">}</FONT></P>! u/ p: o# O! G' ]" Y
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>; J4 {+ m: V) R; V, a
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
: t+ A! N( Q9 y8 {3 j< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
: J$ J% M: Q6 e% m, U( s9 }8 [< ><FONT face="Times New Roman">{</FONT></P>% z' k. H. F2 d2 c3 d5 Q
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>& F7 T8 \- I( q: z0 }8 d5 {& F
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>1 u8 w$ ?* R0 t- m9 ~, h$ I* ~
< ><FONT face="Times New Roman">{</FONT></P>; W3 X. N1 z; i, c  [) W* H8 Z
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
" h5 o+ L- L- u: e( ?< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
0 ^9 ]; E3 W# p( }" f< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
8 H' S" D& W$ }5 p. o9 W< ><FONT face="Times New Roman">}//while</FONT></P>, Y% B$ y; \# R- v
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>. H6 W. E, S! Z% \' v
< ><FONT face="Times New Roman">else return –1;</FONT></P>8 s: W- k  L7 q$ M# P9 Q! s: K* m# _
< ><FONT face="Times New Roman">}</FONT></P>, D! u) D6 Y! [* S$ h! k
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ v* Y$ y1 H* @( Q- x  b, _& m2 `
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
2 E2 {4 h' v; \. y) h5 n< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>7 c) c3 x! Y6 k
<P ><FONT face="Times New Roman">{</FONT></P>: B& p# O/ q( n6 {) l1 |9 a7 ^
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>" f/ D4 v3 b4 t/ e8 g* z/ g0 ?: S! V& j0 ^
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>9 e5 o) e4 F! H5 }4 Q5 b8 i
<P ><FONT face="Times New Roman">{</FONT></P>/ m8 j  b9 _% \. O' B$ R; p. H
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>3 L" F9 p* A/ `- f  u+ \
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>- q0 n8 y  v, B9 ?/ f4 L+ u- Y
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
, o! V$ {. \+ _" e) B5 o4 [<P ><FONT face="Times New Roman">}//while</FONT></P>
7 s) |# @: K( u) T<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
8 H" ?: ]4 y8 T( s<P ><FONT face="Times New Roman">else return –1;</FONT></P>& o2 A# P9 v+ {3 c9 n* ^5 [
<P ><FONT face="Times New Roman">}</FONT></P>
# F( O, V. T0 z. A! ~<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>. G  a- |8 r( g5 x+ u
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% P. _1 C- C  L  @' _
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>. O5 w% E9 c! D
<P ><FONT face="Times New Roman">{</FONT></P>. `, J+ X  j3 s& D$ h" j6 Z
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
2 N& N* t% L/ y4 V+ q8 ^# `9 b3 Z<P ><FONT face="Times New Roman">              {</FONT></P>
) n5 w7 g# S9 E  L<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
$ |4 v) V4 l, A$ m. P$ a6 {<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
6 A" Y+ F* q8 D* K% Q<P ><FONT face="Times New Roman">              {</FONT></P>  I2 J6 h- ~1 o( Y5 y% n1 z; ^( |9 x
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
) I" A3 F! {& x<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
. k1 H: {5 \5 ]6 }& F<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
, t- M% d9 H4 T% ]4 C1 @<P ><FONT face="Times New Roman">}//while</FONT></P>
1 d5 _7 n% j/ D$ H! I<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>, u4 f& n& y+ r) m
<P ><FONT face="Times New Roman">}//if</FONT></P>
# k8 U! N" a2 u<P ><FONT face="Times New Roman">return –1;</FONT></P>
# N& t0 ]0 m  a<P ><FONT face="Times New Roman">}</FONT></P>* R4 Z- O6 {8 C5 n7 b
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' [; L; A0 [1 G( u' a2 L7 W
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
' ^- |* h4 H& ?8 |$ f8 z* ~<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>- u! k5 r# M3 Q: \/ v8 _- p4 x4 k7 ^
<P ><FONT face="Times New Roman">{</FONT></P>5 \* _; t% d# v; J5 r: I
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
0 F* B, j8 ?, O" s% T8 H<P ><FONT face="Times New Roman">              {</FONT></P>
" |8 o5 ^9 \% n! y9 X<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>6 ?2 I& Z5 a; J- E7 g! E$ J
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>. y* u+ k7 g/ H4 M0 D
<P ><FONT face="Times New Roman">              {</FONT></P>8 F7 C6 p: Z2 F$ C/ N/ o+ V+ q) i
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>, `/ M' t8 o% C6 ?
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>+ e& i1 i) I  h7 A& W, A0 \( A
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>4 R3 |# [0 \+ b, u
<P ><FONT face="Times New Roman">}//while</FONT></P>+ H. b6 [8 ?/ |
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
1 t- f3 ?( h* u$ Q<P ><FONT face="Times New Roman">}//if</FONT></P>' D" H* l8 x9 t6 x4 N$ T# G
<P ><FONT face="Times New Roman">return –1;</FONT></P>
% z9 Z* x1 ^, t0 x: M$ W8 p, H<P ><FONT face="Times New Roman">}</FONT></P>2 H# C6 ~& o  l: E- Q& _
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% A: N/ l. f! {6 U& \% q
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" R0 A$ J/ r* g7 `, Z' |  v<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>1 Y6 V$ ^" f; ^3 w8 [; f6 \
<P ><FONT face="Times New Roman">{</FONT></P>" p- u3 Q# E* H, p8 Y6 k# u5 u
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>1 \% s0 V3 U2 j% f
<P ><FONT face="Times New Roman">              {</FONT></P>
. ]- G+ Q! D0 _- H<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
9 h2 M! y6 H0 b& k. D<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
: j2 ~$ R+ k# w1 X% y* S2 i/ M<P ><FONT face="Times New Roman">              {</FONT></P>
+ K: h+ M+ X: P' V0 M<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>8 w5 @+ }6 H7 }3 K; x
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>5 G: Z2 A9 C9 _0 O
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>9 U3 U$ P: T) E
<P ><FONT face="Times New Roman">}//while</FONT></P>$ n6 N9 V( \" L
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>7 Q& I0 s8 M' e# F7 e
<P ><FONT face="Times New Roman">}//if</FONT></P>  r; d# C7 n" I3 R! [% z9 {% ^
<P ><FONT face="Times New Roman">return –1;</FONT></P>8 y& ]- _& ~) {- }' L8 W
<P ><FONT face="Times New Roman">}</FONT></P>$ [/ C; K6 P2 B6 p4 v1 d2 F
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  }, _; H  ?# q! S: a6 H, E<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
7 G0 M* b2 M1 D$ _# m8 C0 A# H<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>% N2 V$ S+ |( V  Y/ i
<P ><FONT face="Times New Roman">{</FONT></P>
. D" h2 i5 t1 G* e+ Y" [; W& k% Z6 v<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
# C9 `* x# r. T' Y, X. z( \2 @<P ><FONT face="Times New Roman">              {</FONT></P>
' Q6 d3 p' Z6 @( Y6 w. i<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>- H9 ~, I% [2 H9 D7 k$ T
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
' L3 ^# Y! f/ {, B0 N5 g<P ><FONT face="Times New Roman">              {</FONT></P>7 z4 o+ h  S2 k: J/ U; w1 e
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>8 a3 |$ S, i+ ^' I4 @; G' D- E- q* f
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
' h* E! r# |! z& x' \; C/ z6 q<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
/ r. t+ T) P, x1 }! e<P ><FONT face="Times New Roman">}//while</FONT></P>
5 r' e: a+ d! s$ ^/ o<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>/ K9 ^# X1 {& v; p5 h0 x$ [! l  g
<P ><FONT face="Times New Roman">}//if</FONT></P>
9 i& {9 Q& c+ U, Y<P ><FONT face="Times New Roman">return –1;</FONT></P>- B) k: S- Z% W7 v3 @0 L
<P ><FONT face="Times New Roman">}</FONT></P># ~& m' j9 u9 d7 n- K" V
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>1 ]" C: r$ m! e5 o
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>8 j2 I: _% P# ]' A
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
3 @% R$ }/ N! {5 v* \6 e<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
8 l' h5 B% j# W: ~<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
% `& c8 T) I% O2 c/ Z) ~' v" Y<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>0 k$ d' f5 I4 \3 J# D
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>" B/ c; }1 [, y
<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>
; n+ o1 {. h5 \8 E, N<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>' {7 A0 B% d& ^  x6 H, r
<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>  i2 I. e1 v$ h5 s
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
1 E, O, g7 L& D, B1 u<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>5 I5 |* ^2 @. P$ a7 i
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
9 F3 ]% E% `/ N4 J<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
1 ?6 W0 ]0 t7 e; W4 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>
( ?  N) O6 e& y7 N9 ~5 j. ?<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
( x2 \9 V1 }2 @* Y2 n3 ^" l  ?5 E<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>1 S- ^! @! f* p
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
/ V7 a* \+ r5 f<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>
0 x0 g) ?! x9 Q7 g. N, `" R<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>
6 L% R" C: z$ \9 S<P >即:middle &gt; left成立。<o:p></o:p></P>
  l5 E, \3 e7 E( r( o4 w5 \, t<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>1 b3 A+ ?5 C. k0 a0 d
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
+ v" f; I7 O# F' }" O<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
% |) x8 D, t% Q! b/ q3 i* e  E<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
, L. d3 y+ P4 X% L4 h<P >∴返回结果正确。<o:p></o:p></P>, D# c, u) t8 M7 |) `
<P >(6)算法6是错误的。<o:p></o:p></P>
$ A5 m$ L$ L) J/ I1 E- D<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>; R9 x) f( G4 \* W3 [' P
<P >left = middle + 1;<o:p></o:p></P>/ [4 C. S  s/ U7 y/ H+ O- {
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
, T! C! X1 x# y/ M5 T6 {8 Z8 q  @9 h; y<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>8 e# Q1 L* k! Q6 R- e
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>* Y5 J! C: R0 I$ i0 l
<P >(7)算法7是错误的。<o:p></o:p></P>/ {. ?$ A( C* s. A
<P >在循环过程中,一旦出现<o:p></o:p></P>
' ^% ^: y0 f! h3 ?) Q; ?" R<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
$ y) q2 W0 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-10-24 02:22 , Processed in 0.367459 second(s), 51 queries .

回顶部