QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2816|回复: 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>& s' p+ L  E, D  e6 @
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
/ l. o6 r" K1 ]1 s6 N& P" w< ><FONT face="Times New Roman">{</FONT></P>
3 u. S& `" f, G2 ~' C( p" T& c: {< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
5 r" h: K7 M$ V7 g4 R< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>3 m7 F+ p" M  N  a
< ><FONT face="Times New Roman">{</FONT></P>
& b, C$ i$ Z6 Q. a% A9 p8 e: P< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P># C; f  ~* ~8 a
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>0 J" \9 v# v% {/ H" o2 y3 R
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
4 `0 C& }9 I0 m$ M/ z: k% n0 B< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
3 j; |1 U7 \4 F% v# `< ><FONT face="Times New Roman">}//while</FONT></P>* }  c/ ?; a- ~. x9 ~/ Z5 _
< ><FONT face="Times New Roman">return –1;</FONT></P>
- {1 n4 Q7 J# {2 `9 e; R( M< ><FONT face="Times New Roman">}</FONT></P>2 j) `* D6 c% v" a" F
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>, o2 `$ f  e- K' C
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
4 }# F) p# \7 q, [2 n% L" s< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
$ w8 {+ b, U' O4 L< ><FONT face="Times New Roman">{</FONT></P>
. I- ^7 |  E/ O5 u+ R5 q( k< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
/ h8 y  X0 J. \  M7 q. t2 h1 E< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
, T9 i7 @+ t0 _0 t7 h< ><FONT face="Times New Roman">{</FONT></P>) C- S( |4 M- R' l
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
/ }% Z# l, P  {9 [* c. X< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>7 w. G/ g% x: J# C- W( U
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
! `/ E) I) I( u$ I6 j" W< ><FONT face="Times New Roman">}//while</FONT></P>
$ Q& Z! n; A; h* ^9 `< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>4 e2 B! k# Q+ ^! o3 R/ k; P
< ><FONT face="Times New Roman">else return –1;</FONT></P>. Y' @9 e/ |$ r
< ><FONT face="Times New Roman">}</FONT></P>% ~6 K" f  }$ \' p
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
4 ]9 d% K- u! P9 Y9 s! H< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 T8 R4 G" e7 P6 f0 }0 A* @5 ~% K
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
: }9 s7 x8 E' @& N* ]5 P<P ><FONT face="Times New Roman">{</FONT></P>3 N1 X- J; o4 Z; \1 R
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
, a8 R0 D+ N" D  f# C$ Z<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>( I: f5 x" |: F& m* H) W0 `/ N  S0 K* S
<P ><FONT face="Times New Roman">{</FONT></P>: O* p5 Q! y/ y5 @8 Q) ^' d9 k
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
, F+ i0 N$ @+ u; h/ U<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>, Q% ?6 i% j9 z+ L  C$ D% R
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>& U7 A+ b% W  Z; T2 m
<P ><FONT face="Times New Roman">}//while</FONT></P>
: V  M& {0 o5 V( W. E<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
5 l5 c2 ]' @( m! x# \* A' H9 m<P ><FONT face="Times New Roman">else return –1;</FONT></P>7 b# Y( |8 h& f, p5 t* L* U( ]& [
<P ><FONT face="Times New Roman">}</FONT></P>8 m4 |! s% U8 W9 Q
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>" B( d) n9 A& ?  g) g
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>' x0 K0 p' B5 r: |$ q+ a
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>0 A2 r1 l7 D" Q
<P ><FONT face="Times New Roman">{</FONT></P>
+ X  M; P& p( E- V; ~<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>) k) E' H+ C/ z
<P ><FONT face="Times New Roman">              {</FONT></P>- P+ c, P  j% q$ K( L% t: o
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
- ^# n' l( o; g; \<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
3 {2 B9 j6 ~, h& A* K<P ><FONT face="Times New Roman">              {</FONT></P>
9 |5 O2 e$ N/ `<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
3 G9 S4 j  ?; g- y6 O<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>0 P! a- U  L& H9 }9 M1 Y
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
- V& ?/ K1 L& a3 J<P ><FONT face="Times New Roman">}//while</FONT></P>
2 c$ m+ T- I$ C: m5 p7 K9 O<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>! ^  R& p& d1 G- L
<P ><FONT face="Times New Roman">}//if</FONT></P>
. `& K$ v( `7 J" Z<P ><FONT face="Times New Roman">return –1;</FONT></P>  Y1 b1 n6 Z2 F7 _8 n& w+ X
<P ><FONT face="Times New Roman">}</FONT></P>7 `& j: n- d; f( o
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
4 R6 |0 S6 d7 }  A1 T# Z<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
) y) V7 J+ u" ]3 Y( X4 K4 L<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
) Z; y( z$ U5 F0 j* ~6 |5 S% C# x<P ><FONT face="Times New Roman">{</FONT></P>
" q. @; A6 Y3 k0 j/ b! z" ^<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>5 b6 u5 [1 F5 c) _, E
<P ><FONT face="Times New Roman">              {</FONT></P>; ?( `8 i1 ^2 G, X" M! H
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
( S) O7 q8 p# j' ~<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>+ @3 d& F# }' e& t
<P ><FONT face="Times New Roman">              {</FONT></P>" C' T7 O; g* D9 m! `  m
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>: ?' Z1 b$ C; X" Z
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
. r  A' b6 g& D6 v2 p) e' v<P ><FONT face="Times New Roman">else left = middle;</FONT></P>/ [6 g% h' n4 {
<P ><FONT face="Times New Roman">}//while</FONT></P>8 y; _& w$ m4 |% p
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
1 }' y9 H' x' m6 I<P ><FONT face="Times New Roman">}//if</FONT></P>
, `$ _% ?: _0 Z: t% q6 o# G<P ><FONT face="Times New Roman">return –1;</FONT></P>
& b  @/ V  a  ]! V' n1 |; A! f8 V<P ><FONT face="Times New Roman">}</FONT></P>
  W9 O; S; S* S/ m, H- ~: L<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; d3 g- W1 d7 x  J" i/ s<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 D# O% P3 O. L6 F5 N3 ?. ^+ E<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>! _) ~  v  \; N8 H$ _/ R) M- K
<P ><FONT face="Times New Roman">{</FONT></P>
- p' E$ A+ j2 ]$ X4 [& I<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>5 k% L/ I. z9 N" P+ V
<P ><FONT face="Times New Roman">              {</FONT></P>
8 x. W/ K) [) ^8 }2 q<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
% ^* p; ~: Z+ y8 Q4 q) J+ [$ x<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
9 P1 H& A5 L/ A/ w<P ><FONT face="Times New Roman">              {</FONT></P>' f1 N0 h6 N  k9 ?+ F' T& Z
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
: \; h8 x. h1 o0 q0 M( G* T<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>+ ~. A% z, @4 i% B. G; \* Q5 J& z
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>% {" }1 h  p; y/ j
<P ><FONT face="Times New Roman">}//while</FONT></P>: {- H( k/ O" J  d3 @/ V6 ]1 x; |# N6 ]
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
4 Z; o1 h: m* s<P ><FONT face="Times New Roman">}//if</FONT></P>9 W  q. {( T; d2 f1 v) D( c
<P ><FONT face="Times New Roman">return –1;</FONT></P>
9 |' a, S5 T+ p8 @* C6 U3 r<P ><FONT face="Times New Roman">}</FONT></P>
2 ~, R  b! l2 b<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
3 o3 \% L" c% F8 {& T( P6 i, A<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>8 e) `; u: X0 q. n
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>, ~" y5 i! _% ^# z/ K1 v/ Q
<P ><FONT face="Times New Roman">{</FONT></P>, [2 Z* u) Y; G: K& P: a  Z3 h
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
6 j! E8 N) t" X7 U<P ><FONT face="Times New Roman">              {</FONT></P>
, @; O2 H$ U1 B6 h* ?2 h: b8 {! C1 R$ |! R<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>* W& R. V4 G9 C6 H# S+ F* n( w1 f
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
6 t" O7 M% X1 j. B<P ><FONT face="Times New Roman">              {</FONT></P>- o( G7 W7 J: m1 f* p
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
% V; S0 u3 ~$ s' p3 |# D<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>! `1 Q# M; F$ q
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>" R; N' K4 y- l! A6 T- f9 f4 d
<P ><FONT face="Times New Roman">}//while</FONT></P>: q( _& [. U# C- P1 @
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>, W9 `3 _( f! s6 Q2 `: j+ e- H
<P ><FONT face="Times New Roman">}//if</FONT></P>( N' f; b) e7 D& o9 H
<P ><FONT face="Times New Roman">return –1;</FONT></P>
6 ^* P1 u2 ?; M8 i# z' o<P ><FONT face="Times New Roman">}</FONT></P>
1 D$ K/ v: f. v4 y<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" c% s3 f3 p- {; p! H5 ~<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
7 x  O$ b1 u  g6 M<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
9 C+ {/ a) ^) t" e$ G7 L<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>& |& E9 Q) E9 B6 N) D
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
5 _- L! M: z* Z7 b" Q8 G! G8 Z# R<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
9 S5 t6 y; w& O3 \: \- c% ^2 X<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>( H2 J/ L. {2 o
<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: n8 ^0 C7 S<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>% ^( v2 ~) y- `+ n' }# j. l
<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>
% A& ~& o/ G4 `0 \; m  ~7 L: P<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>2 H3 F1 {# s/ @9 R( o# K8 K5 h
<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 s* T8 a# k5 W2 Q/ B! `5 E<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
) a. o0 s- V# l$ s9 {- z<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
9 y* q( L3 |4 O- `- `9 a<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>) F5 A  f, J1 B: O, u2 {% I* |
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
( Y8 {  r& A( }! n- r7 N1 f/ y<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
+ s- q! @( o, R4 b; U' g" [* _<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>4 O$ @2 |  q: s  {% i" r: ~
<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>
- y2 m' ]+ v9 P$ H<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>0 i& y" [0 d' w7 i6 i
<P >即:middle &gt; left成立。<o:p></o:p></P>
: c8 u( J3 ^$ J$ 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>
7 r4 Q2 X" y/ @$ [) h4 h<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
8 K0 J; B; ?2 l& W$ Y, Q/ d9 u<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>5 @& L3 |" |" M0 ^
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
7 ^7 V- ]' l+ L8 a& [  `<P >∴返回结果正确。<o:p></o:p></P>" c3 L7 E5 J4 B1 j) E
<P >(6)算法6是错误的。<o:p></o:p></P>3 }& a$ q1 p) Y9 Q: v8 [( ^  V; F
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
2 T$ l' H5 E$ R4 T' m<P >left = middle + 1;<o:p></o:p></P>+ E+ b" ~  x3 T* k: p
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>5 t7 M7 M( f7 `$ j  m1 V
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
( Z5 x% P0 @* @& j<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
+ e* E$ x8 Q9 \# H<P >(7)算法7是错误的。<o:p></o:p></P>
. B5 `. @) E* q! X1 B1 ^3 e4 b<P >在循环过程中,一旦出现<o:p></o:p></P>* e: U9 q: c  m( Z0 j: }$ \* G% f
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>- y: {4 H8 B* d( r7 M4 P
<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-15 00:02 , Processed in 0.418856 second(s), 52 queries .

回顶部