QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2789|回复: 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 x3 T4 h: w! R+ A( e< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>6 c, ]5 d# M8 ^
< ><FONT face="Times New Roman">{</FONT></P>+ Q' ]1 ?( x. O0 h& e/ x, C5 k
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>3 q: t" V) W( Q9 ]0 J
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
5 z1 n. B4 J* H- \) a$ M< ><FONT face="Times New Roman">{</FONT></P>
# Z  d( y* L. w! y5 u* V< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>1 V' |6 Y2 k/ S. c, {: F( y
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>" S  k3 t( _) _1 \
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>& J8 }/ t: ~3 k  x, @% L  P
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>6 L  O" w5 p9 a0 l  y
< ><FONT face="Times New Roman">}//while</FONT></P>
1 D* a2 @- \. L- s: F< ><FONT face="Times New Roman">return –1;</FONT></P>. u" p4 ?: U5 O. v* Q2 W) p; X
< ><FONT face="Times New Roman">}</FONT></P>
! w+ _$ f* u$ V# \7 I" ]< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>% y9 h$ ?- a; l/ T% H
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  k  E, b2 S. o7 G2 r, W( k< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
% ?1 M) u) r& @0 ^0 P# ^, o/ I: A< ><FONT face="Times New Roman">{</FONT></P>
# ~  E3 [8 `3 z3 B< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>+ G* `! m* A- j
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
5 f; B$ D0 H  U' e4 H1 V< ><FONT face="Times New Roman">{</FONT></P>
" E% a, d$ O% ]< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
! k& G$ i7 A) |! }& J; u) E  u< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>6 x: s+ C, Y2 D# @& U! G3 w
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>* ?# d2 F/ s8 ~& |" _6 s
< ><FONT face="Times New Roman">}//while</FONT></P>
3 \0 d+ y7 X8 Z( |9 I# V* z< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
. o$ e, ?( s: @" ~< ><FONT face="Times New Roman">else return –1;</FONT></P>
& P, `1 Q* Y) v( d; ]" W< ><FONT face="Times New Roman">}</FONT></P>
: R2 e5 T  S  m8 |+ l, U: }0 g3 K< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>( u. J, A& B0 d& _/ h# @
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>7 W+ B+ V2 M2 s
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
$ K. h, g. d( P7 ~<P ><FONT face="Times New Roman">{</FONT></P>1 `# |) n, V9 M* Q, J
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
8 U! R( l: O- K" Z<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>+ `7 Q. u- e+ K* M3 E1 i5 p
<P ><FONT face="Times New Roman">{</FONT></P>- H" O1 ^* R8 c& l; I5 W
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>  \1 {1 V; m2 g& x# S  w5 P
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>' _  X2 y1 w2 M5 w& w2 J" s
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>' [$ A! E3 @0 G9 _3 H& y, m
<P ><FONT face="Times New Roman">}//while</FONT></P>
: Z6 f: {# f6 i: K/ ^* c<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- H% D  s2 X% l9 w& c7 W( U( L" {
<P ><FONT face="Times New Roman">else return –1;</FONT></P>+ Z/ K% N8 {$ H' B/ e. q
<P ><FONT face="Times New Roman">}</FONT></P>
$ _+ u- W/ o& O& P+ i% H' Y<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 Q; a$ |" f. T6 F
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ \7 W, R% Y$ H" Q0 q" |: ?
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>& n  ?, X( Y6 |  `
<P ><FONT face="Times New Roman">{</FONT></P>
3 ]7 p3 l9 `0 L, v( N$ l7 X<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>2 p+ a. y' m) n8 o2 Z
<P ><FONT face="Times New Roman">              {</FONT></P>
; S& I8 k$ F6 @8 e- O5 T: E<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
* }0 G& s2 w9 [1 r2 j, r<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>+ w. B8 o8 x3 Q, |
<P ><FONT face="Times New Roman">              {</FONT></P>
! [! v$ c9 m% b' q6 v) k7 r5 Z+ y/ M3 U<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>- a4 J$ L1 c6 @) v1 m( M/ o
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
, v+ p( R! T% d9 b0 X1 h( w<P ><FONT face="Times New Roman">else left = middle;</FONT></P>* N+ m8 ]3 ~( P& K( w* T) ^6 ]
<P ><FONT face="Times New Roman">}//while</FONT></P>/ B1 r" R6 `" c' _1 ^
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>! s8 l" K5 `: I* a
<P ><FONT face="Times New Roman">}//if</FONT></P>2 w0 ]9 V& |2 I8 A7 e9 g6 O1 m9 s( a
<P ><FONT face="Times New Roman">return –1;</FONT></P>6 e, Z) A& V' W
<P ><FONT face="Times New Roman">}</FONT></P>
% f4 q: c6 m5 m( h<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>0 a& c2 a; F# ~) `$ H/ j* K% e& x
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>/ I/ b0 l: ?9 ?6 |- t) }5 M
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
/ J$ f# d( Q  T5 Q+ q<P ><FONT face="Times New Roman">{</FONT></P># j8 c/ T8 K( O! K
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>5 m8 C4 O) G) o6 M8 e' y, j$ ^! o& i
<P ><FONT face="Times New Roman">              {</FONT></P>
6 X% E& a7 i& A4 \# b0 S" v, Y<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>1 \* C& V7 R; f& M7 r
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
) q* M! H! V0 ]& D) Z9 ^) h' ~<P ><FONT face="Times New Roman">              {</FONT></P>0 w+ s: N4 o+ q
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>! a+ E/ {( c9 r, r8 s
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
1 s# H, K# u2 ?, b& d7 i<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
& Q% m/ W! F$ W( F% H1 ^; e<P ><FONT face="Times New Roman">}//while</FONT></P>( \& `0 i1 ?) u4 ?( T0 P
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
8 p* g3 z$ n( [" O* K# G1 b<P ><FONT face="Times New Roman">}//if</FONT></P>
) F( _$ j  W- {<P ><FONT face="Times New Roman">return –1;</FONT></P>
. k6 H  o2 {5 [$ j2 \  y<P ><FONT face="Times New Roman">}</FONT></P>
" j" `3 l1 }+ ]' b2 @! K8 |<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
3 D, A* B, f( G! T! R8 B1 z<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. n: Y; E" G- S2 M" {! D5 O<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
) s7 k! j: b( Z4 s) D<P ><FONT face="Times New Roman">{</FONT></P>
6 G6 J2 E4 l3 w% I# F( o6 t<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P># m, j. ^6 x+ i1 d  a- y4 [3 Y2 J
<P ><FONT face="Times New Roman">              {</FONT></P>
2 C& P, s$ Z5 {% J8 T) u' t<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>9 L+ U& a" k4 s2 p
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P># ]' \0 T! Q. y/ |2 e0 B! W
<P ><FONT face="Times New Roman">              {</FONT></P>/ J9 i- a& |1 L  b7 |# s5 x' c+ k) ^
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>( V3 y, g  Z6 ]) Z
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
* T9 y5 i7 x9 m<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
6 t! p' ?) q' O7 |<P ><FONT face="Times New Roman">}//while</FONT></P># {* Y( g' c1 b# g" W- t& J
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>, `& }9 R% e# U  q
<P ><FONT face="Times New Roman">}//if</FONT></P>* }; j1 Y$ f% T( X
<P ><FONT face="Times New Roman">return –1;</FONT></P>
8 m, u4 Q) ?$ J. V<P ><FONT face="Times New Roman">}</FONT></P>* i- P5 t! h# ^  [
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 v0 P9 G; H& D
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. {% u/ C5 I  \4 J% n<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>7 z+ R# Z/ k; J
<P ><FONT face="Times New Roman">{</FONT></P>: h' K! l$ Q) `3 Q4 M
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>1 D) P3 i: b9 h
<P ><FONT face="Times New Roman">              {</FONT></P>  o4 J, w6 E7 F3 V- p
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>7 r! P- T6 g* A0 G) C
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
3 n/ }+ S0 [" N- K" A5 n<P ><FONT face="Times New Roman">              {</FONT></P>" R7 `8 \, Z, @4 Y  k6 s
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
  Z( D# M7 f0 l<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
. t) O. \4 R7 O6 N9 f<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
9 p) k4 O2 `* S9 M<P ><FONT face="Times New Roman">}//while</FONT></P>: i" [% S8 T/ b+ f& W
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>+ {$ D6 [2 r9 m  q5 u
<P ><FONT face="Times New Roman">}//if</FONT></P>: K5 |' I; x1 @: [0 p) N
<P ><FONT face="Times New Roman">return –1;</FONT></P>
$ R2 A8 p2 i( @! U<P ><FONT face="Times New Roman">}</FONT></P>
" |4 ?7 @! Q. Z+ ?- r<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>6 U/ W# h3 r5 L+ t' j
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>1 z" c' c5 H! W6 J! f$ f
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
  J* @( x/ o0 B) f( j1 u! q! l<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
4 r. F7 k: ], e# e0 ^; A% t<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
! B3 ^" S& g" m7 c<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
% A! ?/ X! s3 q+ Y) T<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>2 G5 _" O5 {& O% ^" B+ g
<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>
& z- r) t# v/ j: o0 G) V<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
1 O# C5 p/ j6 B3 j* M7 j# `<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>1 B) q# W! G8 B2 J3 ~  v
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
$ b. s. q$ W+ t<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 o3 N% P6 v4 M9 S3 w# O. d
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
+ P* h6 ^1 G# M2 f<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
* p) V- q) y! i, q, c<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>9 n4 f" Q  _; }8 [6 z( u
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
) U3 T( b" n9 |; n4 `% c<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
& j4 {2 N8 Y( x+ J: A<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>8 B; ?; F7 U" d3 y" M  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>
2 S- O! F: ~7 y6 Y3 _9 O<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>: P, x( w: D/ \2 s
<P >即:middle &gt; left成立。<o:p></o:p></P>. @* t7 m( s" U; a
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>; I! v) K. A, m0 R5 G. e; n9 E1 _7 H
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
* ^/ G2 B# O! B' r& C, f% @<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>1 Y' J5 c* |& `
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
9 a( G7 A' ~" v9 @4 N<P >∴返回结果正确。<o:p></o:p></P>
, i  ~& Y! D' l9 k3 ]7 A5 Q# l; R+ N<P >(6)算法6是错误的。<o:p></o:p></P>
; _' [9 L; w4 d4 G. d<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
  [! X9 D- i+ Q, ^' _5 Y<P >left = middle + 1;<o:p></o:p></P>
. t# g( C$ [% v# c9 Y: E<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>! @! V* L+ `% P4 b5 f$ T; N( J
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>& k9 j: n5 n/ w6 ~5 J; A, t- t
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
8 _& K1 z3 F  q" K6 X<P >(7)算法7是错误的。<o:p></o:p></P>
+ W  _7 v; y6 _<P >在循环过程中,一旦出现<o:p></o:p></P>6 |8 j$ @7 Q, X# T" N
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
& i8 O( i. N; Y7 h  U: b0 y<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 02:45 , Processed in 1.919987 second(s), 51 queries .

回顶部