QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2811|回复: 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>( R3 T- k0 {' j. c. O
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>( h  v& ^1 _; P- T0 o6 T
< ><FONT face="Times New Roman">{</FONT></P>
& `  o1 ]. v" y4 S0 T& W< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
2 q3 ~7 _& u$ p8 c< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
/ T0 g7 l$ L6 G* V+ W5 A& G< ><FONT face="Times New Roman">{</FONT></P>* h4 Z$ _& H5 k( c% H% g1 f7 c
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
; v/ Q7 E0 E# H  b< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
2 u6 B4 O) G3 e. _< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>) [2 K7 g1 {2 |* ?9 x9 q2 G
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>* S" q& R* s) @# ~( {' g, v
< ><FONT face="Times New Roman">}//while</FONT></P>9 a& _) F8 q+ m; ^! Y
< ><FONT face="Times New Roman">return –1;</FONT></P>
2 n$ f- O  {% o6 K! _, v% ]< ><FONT face="Times New Roman">}</FONT></P>
0 d. F  f5 `* R; P2 A' h< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
. l) ~5 F5 H7 \& i/ y/ Z< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
( N% Z2 J0 |$ Q6 _) w; Z, I< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
# O7 n) B3 w7 _* ^5 R2 v< ><FONT face="Times New Roman">{</FONT></P>
6 J$ E1 a( u$ X5 M" ^! a9 x< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>$ ^) A( {0 w4 Z3 M
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>7 t! Y. w( ?' p  O
< ><FONT face="Times New Roman">{</FONT></P>
3 D1 b" N( q1 B8 \8 T$ A) s< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
5 ~" G5 @5 D7 K, ]( V' J$ N4 p  p" q< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
, o; ?, U' n9 a" f0 Y< ><FONT face="Times New Roman">   else left = middle;</FONT></P>& o/ l5 P4 \8 g, q2 _/ m/ U
< ><FONT face="Times New Roman">}//while</FONT></P>
0 w5 H$ Y$ g: u6 v, \< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>' f. p; e3 r: d' q) L. b6 p
< ><FONT face="Times New Roman">else return –1;</FONT></P>% o  g1 Q  e& P8 i
< ><FONT face="Times New Roman">}</FONT></P>
+ V- Z' D+ _# v: U! q- z2 U, X< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>0 h- e0 b! w* D
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 J1 q- F: ^' T) v4 b< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
" k: W2 g$ A' w4 E$ v+ b; A<P ><FONT face="Times New Roman">{</FONT></P>
" M7 s  ~4 q8 @$ z<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
6 j8 D, b+ L, ]5 r% T) t<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
9 n' w& }# j' |<P ><FONT face="Times New Roman">{</FONT></P>
6 }& W7 Q/ c9 D0 E<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
* H- h! t0 o5 j5 t' F<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
  t8 |/ k/ R" _. |% @* [  }<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>
, x; P  n& f. t6 h<P ><FONT face="Times New Roman">}//while</FONT></P>2 q, ^; f* @# ?- u- W3 k
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- T, A! a/ B3 ~
<P ><FONT face="Times New Roman">else return –1;</FONT></P>
; y8 L4 s" `; @% X; |2 @<P ><FONT face="Times New Roman">}</FONT></P>
8 j/ p/ B+ E; s* r- Y<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
1 P5 n8 a( M+ l0 z3 N<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- t/ `% [# n+ b! D2 s
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
+ i- h  a1 [+ x0 }4 j3 k<P ><FONT face="Times New Roman">{</FONT></P>% B0 E' H/ A7 \; d. a' D/ t4 J, N6 p
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>: K9 J1 T* C) c* w7 J
<P ><FONT face="Times New Roman">              {</FONT></P>& S8 C' C" O0 W. s% u
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>) r% _! U! p1 n% h$ \/ I0 _& j
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>+ T& i* _, x6 x; {1 a- `
<P ><FONT face="Times New Roman">              {</FONT></P>
9 E' a* S! O" X# |- @' o! z' H<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>" `. j0 s: u. L: ~: I( S
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
; @  Q4 g  \0 y8 y$ N1 t; ]<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
0 K& Q0 N- ^, @. h  g- O  W3 @3 g<P ><FONT face="Times New Roman">}//while</FONT></P>5 t7 s2 S3 ]( K+ C
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
! S% |/ A0 u; P6 U# |<P ><FONT face="Times New Roman">}//if</FONT></P># w1 r: b; _4 \1 e# B) |* a0 A9 w
<P ><FONT face="Times New Roman">return –1;</FONT></P>
2 S2 |8 p$ C& V) K8 k8 F<P ><FONT face="Times New Roman">}</FONT></P>% x+ o% n0 s2 U! p! }3 _. S
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
" f+ O; L) d& t( [+ C. j<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>6 B/ L, V) S8 g* `
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>" W- `; J3 D: O: V$ J" G
<P ><FONT face="Times New Roman">{</FONT></P>
# T* @+ R- a+ d. |  o9 B* a<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>7 F8 ]+ A- \% g& n. O3 h" x
<P ><FONT face="Times New Roman">              {</FONT></P>
! M+ `8 m! d# \<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
3 \( W# F1 s/ \2 ^  H<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
% ^6 i9 }5 S0 O<P ><FONT face="Times New Roman">              {</FONT></P>3 @1 E$ g$ t- K! ^
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
/ m! x) D9 E: u0 i# l( i" b<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
% ?8 k  J, p7 P<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
- `1 v2 v# y$ i<P ><FONT face="Times New Roman">}//while</FONT></P>
% `0 E8 ~, z5 D0 g& O/ N5 e<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
7 u& ~: u2 R) A) I7 c9 J% p# X<P ><FONT face="Times New Roman">}//if</FONT></P>: H7 r( o( Z* X. f
<P ><FONT face="Times New Roman">return –1;</FONT></P>
! B' y2 O3 z- ]. S- ~7 A<P ><FONT face="Times New Roman">}</FONT></P>! N* V) v0 A4 S0 `+ ?" c
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
2 s+ }, O+ O+ L' e, U( ^0 b* Y<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  y5 e* G7 a7 [! I7 ^
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
, K( Y  S6 \5 v- O3 j5 o<P ><FONT face="Times New Roman">{</FONT></P>
' h% l( K0 p! W# h: t<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>5 `/ R9 l. k9 P" J. ]* y- O
<P ><FONT face="Times New Roman">              {</FONT></P>- E  @: e: `1 C0 m# a
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>$ U8 n$ E" c/ r' f: C4 g$ Q
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>- A: d7 u/ n. ?
<P ><FONT face="Times New Roman">              {</FONT></P>
0 C6 r4 M+ P( _( z<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>" ?/ c2 L+ E& v( o) @9 ?# m$ G
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>; l. a4 l5 {& Q
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
  @" h& U* `, U0 e4 f  G5 r<P ><FONT face="Times New Roman">}//while</FONT></P>
( g# U) n! F0 H6 S<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
8 n' d. `2 v2 M2 z- c<P ><FONT face="Times New Roman">}//if</FONT></P>
' Z) ?; `2 A# S4 F. V! n<P ><FONT face="Times New Roman">return –1;</FONT></P>) g4 u: m7 m8 v4 k. R; z9 K
<P ><FONT face="Times New Roman">}</FONT></P>
/ R1 E, X" n. C( r: P<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 y1 C: ^6 a: G% {# U/ G<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  Q" f8 D: e5 A
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>0 ?% V5 `. C' c4 |
<P ><FONT face="Times New Roman">{</FONT></P>
; ?- m/ ]& @5 e$ I; w! k<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>! L9 A# ~0 D$ u) @, t
<P ><FONT face="Times New Roman">              {</FONT></P>5 R) d4 a: s7 g8 ?( L
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
/ e( j7 n. C0 j' @<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
% b' ?$ _+ B1 }) `) i<P ><FONT face="Times New Roman">              {</FONT></P>
* j5 z, z. q& b<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>, z# R) U+ I4 s0 i$ ^8 R5 s9 W( c
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>
8 W7 V# x. ~1 A9 q6 d2 _6 \, S* W<P ><FONT face="Times New Roman">else left = middle;</FONT></P>( u; w3 r+ P5 G$ T) i
<P ><FONT face="Times New Roman">}//while</FONT></P>
, u/ u$ F0 c: @- O; i<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
3 o) I( ^+ k% {, x9 J3 b<P ><FONT face="Times New Roman">}//if</FONT></P>
0 }: C& p! {1 m, E3 S<P ><FONT face="Times New Roman">return –1;</FONT></P>
" r' u/ ]' v. v+ F% _<P ><FONT face="Times New Roman">}</FONT></P>% D3 A* l+ M5 V1 K+ n$ a
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
7 k" _3 ~2 D0 ]8 Z' {<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
2 T$ \; _: F& U0 B! b  `" [<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>" T" B5 `, I- k7 p) [
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
1 X& F8 i& ?0 G5 j! e<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
& m  {! v; ]: G<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>! z$ v; u: A' T
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
2 C; h9 L/ X" w8 L<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>
+ B! H6 l) F4 E$ ~5 [& L6 \# f<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>& ~1 w) k; \! ?- A1 X) W6 u
<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>
" z; S3 S5 Y) N% z  V<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
. U. T# _: b' |( W<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>/ N4 S' x6 t$ g! a2 J/ P4 F
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
, W& [  p3 t6 s7 i; R7 g+ `! d<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>) q9 H# B6 J4 X- @3 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>3 @) {6 S% W" ]7 t6 [1 w' ?
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>, ~) T! ?5 P/ F& t0 {
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>0 O' y" j7 a1 C" h6 }* g8 m
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
  E0 I: j6 r+ t  N1 g" Q<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>
; Z, z) ^! E5 n* @$ o  Y7 D! ~# _<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>
* F2 s7 }8 ^: o<P >即:middle &gt; left成立。<o:p></o:p></P>
7 W2 j7 p2 A' z4 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>5 {- V/ I% X8 V9 o  W% r' v
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>- M5 v6 ?$ g7 {
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
$ j4 g3 z* w1 g2 b$ n# o<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>4 H$ @* b, @" q* y, R& x% a6 G. e# z
<P >∴返回结果正确。<o:p></o:p></P>
# D/ d) D: J* w<P >(6)算法6是错误的。<o:p></o:p></P>
$ a/ i) N% R6 Z9 c8 c: O5 t1 `<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
5 R" m4 G- S7 {& h3 R: g! P/ G4 o6 J<P >left = middle + 1;<o:p></o:p></P>
4 _5 c. g) w: w8 z7 ]2 u0 I9 ?<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>$ F! A$ |4 T* c) A- F
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
; K6 }1 H2 w& e6 y<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>! M/ b1 p( X$ U/ t
<P >(7)算法7是错误的。<o:p></o:p></P>$ U$ y! w3 p2 A9 m1 J
<P >在循环过程中,一旦出现<o:p></o:p></P>6 Q0 H2 f$ F3 n! {9 }9 x
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>. J4 r0 Z5 n( i  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-6-4 07:05 , Processed in 0.446692 second(s), 51 queries .

回顶部