QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2840|回复: 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$ V5 ~  e) P3 |: |6 q< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
6 M0 J7 Y3 B4 z8 t9 i) ~  [< ><FONT face="Times New Roman">{</FONT></P>
/ g# G3 [+ Q: c# }- c, D< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>% B& m5 u" |7 s; n' \9 k
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>2 J1 \$ c4 }1 C& b* m$ a( Z
< ><FONT face="Times New Roman">{</FONT></P>
& }3 t7 A- _4 H0 g; ?* G! t- L< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>; I# h& _" W, {2 ^9 A5 G! V
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
$ c- y5 I* D, B; b8 H< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>, V/ _/ N; M! k) M0 A  U
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>3 U, }- Y7 d7 h7 Q) S* M. F/ A# D
< ><FONT face="Times New Roman">}//while</FONT></P>. c# E2 B0 S# D" X# ^
< ><FONT face="Times New Roman">return –1;</FONT></P>
+ W3 [2 B5 l, ~- q+ O1 Y7 V  L& R< ><FONT face="Times New Roman">}</FONT></P>: L# |3 k$ {) J8 v
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>$ d. N! Y0 D( Q7 h) O8 e
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>1 g# j  u2 c1 `* I4 [
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>  c3 I$ P  x( `3 k
< ><FONT face="Times New Roman">{</FONT></P>
1 B8 Z# I- K& Z: X< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
1 @9 ?, m& S  W4 f6 G! {" O% k9 e% K< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
7 j# u+ d8 ^" q< ><FONT face="Times New Roman">{</FONT></P>+ w, S' |; g; b$ G7 j
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
- E- Y0 l7 H- @/ z9 t< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
& K! D1 j4 P" d* _# L1 X% h< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
1 j$ z" L& l, J$ `0 D- t0 A, {4 F< ><FONT face="Times New Roman">}//while</FONT></P>7 p3 L! H, j4 [# m8 d3 D2 s
< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>- H/ t; s8 _; h3 D0 z/ S& W( R$ _
< ><FONT face="Times New Roman">else return –1;</FONT></P>: l) [2 T4 f$ n( x* A/ o
< ><FONT face="Times New Roman">}</FONT></P>
& X9 X2 v' Z( ]8 M! T< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
' X5 r; A3 Y' R& E1 V& a" c1 a& z< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>4 N4 r- l# j4 U( h- Q6 U' P$ o% `9 ?
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>8 h1 E; _6 w% z, ?8 `/ ~0 k& y7 N
<P ><FONT face="Times New Roman">{</FONT></P>0 ?7 d$ U1 R0 d, a5 e# W
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>; C7 q% \+ `; M/ n
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>! E! c# r# f9 }/ Q( k" m
<P ><FONT face="Times New Roman">{</FONT></P>9 F# s0 i' ?3 j% \$ ?: q
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
% x) x* b; i: T<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>
7 E+ J4 f3 s) h<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>4 Y0 @  q& Q' i* y, U
<P ><FONT face="Times New Roman">}//while</FONT></P>
  x! }& ^' \7 D, ?4 k<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
# D3 p0 Q; e, ^8 d9 \" R8 q; l<P ><FONT face="Times New Roman">else return –1;</FONT></P>
4 U3 L( n& C) I! w( G7 U<P ><FONT face="Times New Roman">}</FONT></P>
% O/ y, X" N# a8 `<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; ~( _( e9 k8 t& S  q<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>: b" c1 @; r; G7 a9 N" A) i6 o
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
' d- e1 x+ g" \7 U# ?- S8 F7 W7 M<P ><FONT face="Times New Roman">{</FONT></P>
& O. I* K3 \. d; b  v- i3 i<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>8 B, p0 a% ?5 d* x7 R( ]
<P ><FONT face="Times New Roman">              {</FONT></P>
4 ^8 q/ Y7 A$ B4 I! `. B! X% s) f<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>, X( w, M* }+ }7 G5 `, F9 o
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>/ }- x5 G% s) l* P! y
<P ><FONT face="Times New Roman">              {</FONT></P>7 E( D1 y) }# q; T
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>8 N0 R7 r0 u# ]/ q
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>; I0 @. r- X2 \8 H: s
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
' Z: Z0 `. M  w( y- G- P  r<P ><FONT face="Times New Roman">}//while</FONT></P>, d; D4 ~! X6 D
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>9 B0 E& p" i* n
<P ><FONT face="Times New Roman">}//if</FONT></P>
2 q* d+ l9 n& S- O% Q<P ><FONT face="Times New Roman">return –1;</FONT></P>8 Y$ ~) q: k2 H, p) z
<P ><FONT face="Times New Roman">}</FONT></P>
3 A" f7 z( {) ~0 c' x7 y! {& M7 v<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
  x- I5 c  D, Q<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 u( K+ Q* P+ v& y
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
" c6 R8 R: M+ G& x/ b<P ><FONT face="Times New Roman">{</FONT></P>
% Z7 v, ]0 }, {; }1 i% \% p- J& q8 m<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
2 t& L' S. }. B- w: p0 c<P ><FONT face="Times New Roman">              {</FONT></P>/ F1 T7 ~3 Y' M, K6 u! r1 l" {6 [
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
! d0 o! |3 D. N" `! y<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>9 U8 Z# F8 v4 U- c6 y) B3 |
<P ><FONT face="Times New Roman">              {</FONT></P>
' X1 o9 B2 s, ?8 U" p( I% {<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
; D- ?) N7 f: Q<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>, h. o" Z2 p3 |/ O
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
9 D$ K) t$ d! N* l2 Q<P ><FONT face="Times New Roman">}//while</FONT></P>* G7 r; y- Y- \0 {; g
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
( ]5 I9 |. I; {) @* `2 l: C<P ><FONT face="Times New Roman">}//if</FONT></P>
0 U; u4 N: L$ @2 `& F* x<P ><FONT face="Times New Roman">return –1;</FONT></P>3 F$ S% }5 N* C, _3 S9 N- t( Q
<P ><FONT face="Times New Roman">}</FONT></P>
  x) N" r# T% g$ l<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
$ }' {! G; i+ m" T' ^# w5 _<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
+ L# ^1 l( |7 N2 v) D/ F/ F6 N<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>1 \! P- B/ z) F) W
<P ><FONT face="Times New Roman">{</FONT></P>
' [( u3 u, V4 N0 z5 R# G8 U) \<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
; @% r: d. Z6 x<P ><FONT face="Times New Roman">              {</FONT></P>4 S' l' L' i" N: m2 b
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>4 X8 Z' p* i, A7 }8 T
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>- i( Y2 \& t9 i
<P ><FONT face="Times New Roman">              {</FONT></P>5 A' r% ?8 A  N1 R+ V
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>6 |. u3 f0 W6 o! v0 G
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
) l, ~: J& z, e<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>! ?$ g& `9 e! C: g" i& W  D8 C
<P ><FONT face="Times New Roman">}//while</FONT></P>$ U. L9 b% g/ ~. _9 z
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>2 l# y6 N; K; T$ q& Q+ W
<P ><FONT face="Times New Roman">}//if</FONT></P>7 X9 [- Q# ]8 n1 N2 Q
<P ><FONT face="Times New Roman">return –1;</FONT></P>* Y: U1 r% `: g- G+ b
<P ><FONT face="Times New Roman">}</FONT></P>& H7 K( s5 u' ~) `9 A/ ^
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
7 ?& e, v8 S/ S. I5 \8 E<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
2 M+ a, |% I# m& Z2 C! U7 S<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>* i" f9 d) S7 p4 k1 L! @
<P ><FONT face="Times New Roman">{</FONT></P>  V, O* J" l% h6 A& Y
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
$ }$ X, ~/ o/ a( [; X0 L<P ><FONT face="Times New Roman">              {</FONT></P>
+ X8 y9 `# [4 }! Q+ z5 m<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
" o9 }0 _3 P* ^4 \' W<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>' K- R+ G, ^3 {6 T) c! b* W
<P ><FONT face="Times New Roman">              {</FONT></P>" e8 k2 l4 O( X+ B& i9 u* \: v
<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>/ L! y# ^0 Q% E  R+ w3 j
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>; L/ Y6 i& ^" p7 w5 L) E/ F$ n4 m
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>& V3 P2 V( B$ \+ k
<P ><FONT face="Times New Roman">}//while</FONT></P>, k$ q$ i) `1 d; j; V. P
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
$ @' ^! M1 Q. A" s2 c  {7 z+ |+ C<P ><FONT face="Times New Roman">}//if</FONT></P>2 Z5 X7 g3 X: t+ T: R, b( ]: u; C, X
<P ><FONT face="Times New Roman">return –1;</FONT></P>9 I5 d9 i& ^+ B+ G( X
<P ><FONT face="Times New Roman">}</FONT></P>
9 I+ |  P6 ~1 y  V7 U<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% d! y+ a; F+ [<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
5 S6 B! ~2 E) o<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
; w# n+ q" V& [3 g7 u<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>3 u7 O0 D, ~; N5 ]; a/ Q, b9 }
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
- p9 m3 n; ]  \; Z* s<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>2 c1 f: C5 _+ a* c% |
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
0 L+ F! D0 i) U# A* w9 f<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>
! y+ [: d3 T- D<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>7 g3 ?$ S& c$ Z. ]  Y
<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>
" G( L% H/ O, P/ h! Q<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
* }" B/ Y+ f/ I) Z% j<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 T: E; s/ h* n, `- N<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
% e! @4 w8 [/ ]6 c' O<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
; w) J' a+ _0 V$ J, y<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>7 m3 F* f# a7 q4 F' R8 o% z  c+ N4 n# g! g8 X
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>* _4 G7 V( i& A( I; p7 V
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>3 Z& z7 i2 ?5 d
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
8 V+ j( z$ |- p5 t& ?6 h- g<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>
3 j9 y6 u5 w* e<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>+ U& Q! E+ V/ _4 b+ R# I3 F
<P >即:middle &gt; left成立。<o:p></o:p></P>+ _$ l/ ^; I3 C7 E# c
<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 d" a! A2 Y8 b( c
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
: c, U% v# a0 j  H: M) y+ u5 s<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>8 z- y; g' M/ f5 T  N" B
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>8 D- f% b* [. \: y: k2 ?' i
<P >∴返回结果正确。<o:p></o:p></P>1 i' i) X' Y  l  m
<P >(6)算法6是错误的。<o:p></o:p></P>
/ W, \. b5 c+ _; `4 a<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
$ ~" }7 b: Z* D<P >left = middle + 1;<o:p></o:p></P>
! \+ v$ d2 }2 I<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
) T& }- `" u" y* a6 ]" a' x<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
+ K+ t* k4 f2 ?/ j/ i6 O) ?<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
" P) R3 \' o4 e% f6 I<P >(7)算法7是错误的。<o:p></o:p></P>
* A& i' U4 Z% p5 m) O% N<P >在循环过程中,一旦出现<o:p></o:p></P>
5 }$ b: a, F5 }7 e0 H/ X0 R<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
' L- D4 `7 ]# _0 s+ ?' N  h<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-7-22 11:15 , Processed in 0.487767 second(s), 52 queries .

回顶部