QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2774|回复: 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>
) g5 ^: w0 i. k0 w, c8 ^0 i6 L< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
7 H6 F8 A- B1 {+ c. z; T: w< ><FONT face="Times New Roman">{</FONT></P>
" p6 n& c$ Z* @  @< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>( ~$ B: K- u4 m1 o4 D# B
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>4 ?& g% d, E) h
< ><FONT face="Times New Roman">{</FONT></P>
$ A% c% k# `! }* s& w9 c# C7 ?< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>' ^2 `- |/ |+ o4 s
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
% ~- T7 X- }3 @# _% C0 d< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>
1 [, J& P' ?' a< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
1 Y8 S) P. r$ `< ><FONT face="Times New Roman">}//while</FONT></P>" a& b& l: w/ R; t0 D7 N
< ><FONT face="Times New Roman">return –1;</FONT></P>& j2 z+ a" ~+ U( o- |* ^& M; _% {' A2 x0 s
< ><FONT face="Times New Roman">}</FONT></P>
2 H$ N4 b$ z/ _0 q! K+ M  Q$ P< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 y0 H; u7 _/ }1 H4 @, W< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>2 E4 B, R* g7 X0 w/ o' ^$ M
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>' D2 P* N7 K6 i5 W6 g
< ><FONT face="Times New Roman">{</FONT></P>
8 n) k; v) e9 I< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
1 p  U. n/ z* |# l< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
8 d" u: f7 R$ Y; e( b' Y< ><FONT face="Times New Roman">{</FONT></P>/ F4 A! {% @, M1 O) s7 X
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
# ~/ s) c: G1 |. w' E- l4 [5 C< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>+ Z! |/ F: _0 y& A, t1 m
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>
% M% t6 S1 Y* J  C! |" B4 J< ><FONT face="Times New Roman">}//while</FONT></P>
8 v; O6 C1 g3 H& M  {< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>: b$ r# i. Z; o2 m& ~$ U+ p+ d  p* u
< ><FONT face="Times New Roman">else return –1;</FONT></P>
$ o3 o) V  o0 t% f. W< ><FONT face="Times New Roman">}</FONT></P>6 r- P" ~, L+ x  c% \; X) T
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 l( m; {* U0 U7 _6 x: y  N
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
4 Y8 T: d. ~% g3 P+ Y: O; Z$ m< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
5 U: z& x1 U- P<P ><FONT face="Times New Roman">{</FONT></P>
' q4 J( |( C) w$ f6 w, D% C1 I<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>; {& R; f3 @5 t0 z3 a5 h) y
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
" z. I/ |( D' F- `. K3 J: G& N<P ><FONT face="Times New Roman">{</FONT></P>+ g) n, Z" t: s( h. [4 }- u& Q5 I
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>! G; G8 U" x) b! V
<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>* V1 N: u: g7 }4 D$ V- L+ D* V# M
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>, d0 g0 K5 f9 g: G- E: l
<P ><FONT face="Times New Roman">}//while</FONT></P>4 @2 x5 E$ z9 S: `
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
0 x7 f% R9 h4 ^6 G<P ><FONT face="Times New Roman">else return –1;</FONT></P>
! e4 z4 Y) \! I. `) n  f<P ><FONT face="Times New Roman">}</FONT></P>! ]5 ^7 q- A: N* c, ~
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>* j4 H# Q, C5 ^* M
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>& r1 {& `6 z& C% |
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
* s+ ]! y7 Z% F+ _' O5 u<P ><FONT face="Times New Roman">{</FONT></P>
5 b% A) g" m7 ?+ P1 C9 j  A- D' M2 W<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
, J* e! D8 Q% }5 G- C<P ><FONT face="Times New Roman">              {</FONT></P>1 U! e! n, b: N
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
) m  M8 q# Y- n. R( I1 s' H9 U<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>+ f' h4 ?  Q- `' m+ a" A8 n
<P ><FONT face="Times New Roman">              {</FONT></P>; @! s/ _2 c; @( f( K) X
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>) X4 T- z+ @1 C$ Q; h9 j8 I
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
5 i3 ?* N- p" q& x. O<P ><FONT face="Times New Roman">else left = middle;</FONT></P>* m, Z  d% }4 U" c# |
<P ><FONT face="Times New Roman">}//while</FONT></P>
- C; e/ h) q+ M, b. t7 G<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
' j1 E( H5 |; d9 H, p<P ><FONT face="Times New Roman">}//if</FONT></P>
& _, |% o7 u! z" P9 @1 q<P ><FONT face="Times New Roman">return –1;</FONT></P>
* N5 p2 K8 D) D! H2 v<P ><FONT face="Times New Roman">}</FONT></P>6 @. \, l. i- Z8 K& w% r+ J& v
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
& i& i4 T5 [# Y8 {<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>$ q0 A) S  n8 E* h, F9 y
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>3 t' I# z+ P( w
<P ><FONT face="Times New Roman">{</FONT></P>
( E, {/ H1 L( L<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
) c* \2 k" ]+ R4 z& E. s& m0 }* C<P ><FONT face="Times New Roman">              {</FONT></P>
. a  ]9 m1 T! X8 P! V<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
- ?. ]0 ^! p# q. ^<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
& ^; T1 X/ {4 x! S1 h# K/ V<P ><FONT face="Times New Roman">              {</FONT></P>* u2 ^/ Y9 z. k: Q7 ?8 U+ J
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
$ I! E  N, j: [8 W% Y1 x<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
" \7 h0 j3 a. E  q3 H+ \<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
; _1 a! A7 _# d, w  W- v<P ><FONT face="Times New Roman">}//while</FONT></P>$ n$ A0 ]) g. ^+ n4 s
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
  c. N( e" }. p7 @! L' {: l<P ><FONT face="Times New Roman">}//if</FONT></P>
6 c8 H+ r! Q2 N6 q<P ><FONT face="Times New Roman">return –1;</FONT></P>: A3 t: N/ a! X& l, G. B$ W8 ^
<P ><FONT face="Times New Roman">}</FONT></P>; B: D& g7 [( h5 g* m: `+ z
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
& t8 e( g; A, y) p0 C<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; @& u: t+ {) z( y" }% i: _( e, `<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>* {( s1 m' |9 ?1 _/ z5 ]! n
<P ><FONT face="Times New Roman">{</FONT></P>
# M& b# V' X9 X+ q% j- ]<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>2 V+ N/ p7 I4 ?6 q
<P ><FONT face="Times New Roman">              {</FONT></P>
5 ~4 h/ W& g8 A& i6 x7 A<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>% s# o8 i1 o& p" a( T: a
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>( J5 ~' `4 m1 Q5 C
<P ><FONT face="Times New Roman">              {</FONT></P>' C7 ]+ T# T, {5 C* `
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>
$ j. F3 G- x7 x) o/ H<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>7 A6 ?, u$ e+ j) @; G  ~+ k& F  s7 i
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
6 T3 l: O5 M! ~6 S) a' V; c) q2 |<P ><FONT face="Times New Roman">}//while</FONT></P>% U% X$ H" y5 s' Q2 _9 q
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>" k# a0 w, p7 J
<P ><FONT face="Times New Roman">}//if</FONT></P>
) k2 n0 V1 D4 x) E1 r2 r& F. [<P ><FONT face="Times New Roman">return –1;</FONT></P>. L' p  S" d4 H2 O+ O
<P ><FONT face="Times New Roman">}</FONT></P>
9 J- c' [! u. X  V6 U1 A% E% [  G<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* b) J" u. ~3 W# r6 L4 I, s<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>, A! C! V+ X' R: R% ^2 W) i' R
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>
2 L1 ~0 c. q- w7 M<P ><FONT face="Times New Roman">{</FONT></P>
1 T5 W% D/ u, Y& n' i& H7 s<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
5 M$ k4 o$ }, D<P ><FONT face="Times New Roman">              {</FONT></P>
0 Y, `' b: r( N/ e4 C( J+ d<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
2 A6 I* P7 V$ T, G8 Y4 Y" R<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>) A( B/ O; y1 F  ?' s7 r  d& s* a
<P ><FONT face="Times New Roman">              {</FONT></P>
6 s& C" z9 g! d7 }2 [& B2 Z6 A1 s( P<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
$ J/ f$ O- ]1 F  o! Y' g<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>3 c( `3 T& R: s, X# E3 V9 v
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>1 R( ]+ r; G3 U9 x0 ^$ N- C
<P ><FONT face="Times New Roman">}//while</FONT></P>
5 l. T7 `  T) P<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
* d2 C/ c3 @7 b0 Z# f; e<P ><FONT face="Times New Roman">}//if</FONT></P># C: s3 D4 }3 Y( f! a
<P ><FONT face="Times New Roman">return –1;</FONT></P>8 ]/ |5 m' q5 M& J& W# m$ s
<P ><FONT face="Times New Roman">}</FONT></P>% H. ^  i2 K0 \' C# f
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 @9 [6 K" S, g
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>! b* w' a0 V* M, Y/ l0 j- j4 ~
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>: l. {$ U- E* m' H
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
3 x0 R! n7 @3 s+ h$ G, m% U<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
8 u2 j7 r% Q: L8 }<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>
- v1 u2 Y, [: i$ U( U( r$ T<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>/ W: {7 I- A( }) K% \) @' b% {
<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>7 O( C5 `7 m) r
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>& q5 l& i, n" w+ i3 x
<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>
8 o. o9 G8 R* M8 j7 H<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>3 e  d# X3 N* `1 M: G$ 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>
, D# Z. d2 g) O# c<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
& g, j  e. W0 m( ^8 [<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
+ g. s# k7 ~, U% T) s6 B2 W8 s<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>
/ w# R9 o3 `, q0 a" L, Q<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
8 j2 ]- w  E/ M- P  j: i<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
+ B2 Y+ y* ?' d# s( D<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>6 f' [6 H* K! U8 B4 [. S4 U& 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>& M/ N3 j) W. [" P% P; 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>
+ S$ ^% l9 S: X2 @/ B* u<P >即:middle &gt; left成立。<o:p></o:p></P>4 r8 {& I  |# j9 I; M) l
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
  p2 E1 b1 Q. T, ]<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
  l" Z9 r0 r. ]- c: N5 M<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>' \* a" a, g- S' p* _" q
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
3 e% b6 I6 H% w7 P: C<P >∴返回结果正确。<o:p></o:p></P>  D7 a' u/ w3 T% M9 F
<P >(6)算法6是错误的。<o:p></o:p></P>
4 Z1 R( a+ ]0 U8 t/ \<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
3 w1 Y7 F5 v9 L6 c<P >left = middle + 1;<o:p></o:p></P>+ U% P+ E; U6 n$ d7 U
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>& v* v5 J' s, Y
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
( t2 L3 K- a6 ^$ E& R<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>. R" G/ r8 p7 U5 {
<P >(7)算法7是错误的。<o:p></o:p></P>6 G% e, Z8 W$ w
<P >在循环过程中,一旦出现<o:p></o:p></P>
9 c3 M  y6 n1 v2 b<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>: z  `5 h$ [; i3 ], ]( Y, x
<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, 2025-12-30 07:13 , Processed in 0.774937 second(s), 51 queries .

回顶部