QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2793|回复: 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>
; Q- V- y3 ^1 i1 x< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
4 R3 u" O/ J) _< ><FONT face="Times New Roman">{</FONT></P>+ Y8 J* e6 Y% R5 a# t
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>& y) H0 E, \  u% t
< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
/ b/ P+ ]+ K3 M/ J& r1 j. s< ><FONT face="Times New Roman">{</FONT></P>
6 Q1 O' Y4 P( E+ U  K( c6 n) G< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>* r( n0 n  M1 d  O! I$ n
< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>2 o* P& q' c& |' \, E
< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>! Y! i( g: R0 T( ~" f9 Y& G& v& ~
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>6 n0 o$ a- u4 y
< ><FONT face="Times New Roman">}//while</FONT></P>& p' M6 I+ X, s1 @, R9 S
< ><FONT face="Times New Roman">return –1;</FONT></P>
3 Z% Y0 i1 n' B. U# Q' w/ l< ><FONT face="Times New Roman">}</FONT></P>
, I: Y( c2 q3 I; l+ w< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
7 t1 p. u; ]1 k* J, B! F: Q< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>, c  M. H% }' ?5 L9 y( F! `& Z
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>* V% D: [/ }6 Z# F  o% \
< ><FONT face="Times New Roman">{</FONT></P>8 ]9 `! Q/ E' Q1 f- ]
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>) F  C/ p* ~+ {/ j
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
: R, H' \7 D( [; S< ><FONT face="Times New Roman">{</FONT></P>
  K- F- q$ [" w6 `< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
* \) v/ K- f( T6 X5 F5 S/ D< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>2 R4 }, v5 `" v8 h6 y
< ><FONT face="Times New Roman">   else left = middle;</FONT></P>1 @) l7 d8 j4 P; j7 m( y
< ><FONT face="Times New Roman">}//while</FONT></P>
, G( p. a4 R# G% g: l! Y6 f" t< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>' O0 H& h, e8 }7 {4 d3 J; r
< ><FONT face="Times New Roman">else return –1;</FONT></P>& u: a$ w8 P9 y% z  z0 h
< ><FONT face="Times New Roman">}</FONT></P>: X% ^( V% f# t. ~, }
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
! V. _% {) l/ Q/ t4 Z8 a< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
6 Q' A& e$ V7 u< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>7 c1 s  F$ N# M2 N  D$ o
<P ><FONT face="Times New Roman">{</FONT></P>8 S/ Y3 `5 V8 X' O
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>3 [% O; o* T$ t$ R# D
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
- R9 E" I2 {0 i: u( ~# C* S" U/ S<P ><FONT face="Times New Roman">{</FONT></P>9 H% `  X$ {- o: [
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
8 ]/ P# G& s! ?<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>" j+ B" r. i0 ]) D$ |* N
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>! r( a9 ]- T3 a" Y1 Q
<P ><FONT face="Times New Roman">}//while</FONT></P>5 n! d/ e2 L- V) W! _  j7 h; r
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>1 `1 S" ]- S- D1 f1 w9 f9 q' y$ R
<P ><FONT face="Times New Roman">else return –1;</FONT></P>
( X0 Q! d+ u$ R# X/ T& |( I<P ><FONT face="Times New Roman">}</FONT></P>; X1 H) p; I6 Z' n6 }
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>9 L3 N8 ?% h1 z' u3 b
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>& b6 K) y$ S) N
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
% ^7 O1 O' L, ~$ V6 i<P ><FONT face="Times New Roman">{</FONT></P>
% H0 o9 m% A% ?<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
* D1 J1 E/ b; l) ^5 I4 p<P ><FONT face="Times New Roman">              {</FONT></P>
% H% I  @/ C2 {" y<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>) y# g) A  x! t% E# @6 e6 M5 v8 Y
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
8 `% P1 H; k8 l$ @3 @<P ><FONT face="Times New Roman">              {</FONT></P># E6 i' n/ ]0 {$ h9 L
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>
$ c! j. u2 d, k$ `& A<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
% k3 t$ N# C! u+ q) Y# |' B<P ><FONT face="Times New Roman">else left = middle;</FONT></P>9 y% r* S# h3 S3 _
<P ><FONT face="Times New Roman">}//while</FONT></P>1 H+ V' e% @! j# [
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
) C" a: d" ?% u7 j' v$ S9 a<P ><FONT face="Times New Roman">}//if</FONT></P>
; r# w  v3 @; }8 g; I/ Y2 T<P ><FONT face="Times New Roman">return –1;</FONT></P>9 V8 I6 |3 O5 y& o' U2 T6 e2 c8 ~
<P ><FONT face="Times New Roman">}</FONT></P>- l  V$ A0 s/ N" w
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
6 L$ s# _6 z- ~8 s<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
; ]- ?; U$ J7 @, r% T4 `6 M3 j1 U<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>* I$ m! ^; z- L* Q6 ?  v
<P ><FONT face="Times New Roman">{</FONT></P>
6 i) P  ~, `2 J* `6 q* @; |<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>5 `0 ]: p, j) ^' |5 f/ L% v
<P ><FONT face="Times New Roman">              {</FONT></P>% t9 \' p! {/ S9 S9 ?% g4 h- v2 @
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>$ I4 y: \0 l) d# \' X; Z- }
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>7 x. Q" C* z# l
<P ><FONT face="Times New Roman">              {</FONT></P>
* {1 o+ h$ A' V  a- G<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>$ ]+ e: O, j; |# a6 ^
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>8 C( @- X6 a+ S6 i: l
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>3 u; F* i, r9 g! X% k
<P ><FONT face="Times New Roman">}//while</FONT></P>; w" b! ]0 Z$ _' H+ U
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
+ _6 m9 |7 n" O<P ><FONT face="Times New Roman">}//if</FONT></P>5 [+ _7 C- |) d5 Y8 h
<P ><FONT face="Times New Roman">return –1;</FONT></P>& F- @* Y4 n7 J: R, H
<P ><FONT face="Times New Roman">}</FONT></P>6 X$ o4 J6 D( [2 q- M
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>3 B# w  S1 s1 `3 i6 Y- r) ^
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
9 _# H4 c* q/ Y4 O<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
. R! b8 i( K5 o<P ><FONT face="Times New Roman">{</FONT></P>
. q: p- _: L9 r* P<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
) ]3 C2 @# L0 O1 D2 s5 q" B<P ><FONT face="Times New Roman">              {</FONT></P>- [! s: ]9 @" G
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>% I6 ]$ V) K' F) K& ?- y' Z( R
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
4 [* e1 r+ i. [: k. z- y7 `4 x# Y5 {) B<P ><FONT face="Times New Roman">              {</FONT></P>
; D  s( N& u" r6 z# W1 j<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>8 H5 v' ~0 x. b( x
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
( k- ]' h( m4 J* w: ]3 e; E! P<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
9 l5 S9 a2 ?  n- P) t; x<P ><FONT face="Times New Roman">}//while</FONT></P>
4 h0 @6 c$ Z3 `" E9 W0 j<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
* K# J" i8 D; a  F* T<P ><FONT face="Times New Roman">}//if</FONT></P>2 |; }$ b  I( a0 C8 f8 u
<P ><FONT face="Times New Roman">return –1;</FONT></P>
; Y7 _  u9 e* L& ]$ W<P ><FONT face="Times New Roman">}</FONT></P># f- R. f+ W4 p& C
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) z( _5 |- V& w, T. |* j* P
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
( H4 A" _" s- Q; k3 I) @0 c<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>
! L2 K) ~# Z8 @! W1 ~% \<P ><FONT face="Times New Roman">{</FONT></P>
8 D* q; p8 o$ \5 }6 N$ g: g5 n<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
& O# t/ {8 R3 B) Z<P ><FONT face="Times New Roman">              {</FONT></P>
1 b+ }. D  w9 s, s8 Z& v<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
* [3 C' X* l% T  O/ B) O* r5 d<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>
9 p/ Q. F3 B9 u$ x) o3 n<P ><FONT face="Times New Roman">              {</FONT></P>
4 x( N& q2 r' [/ C3 h& f2 @<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
, Y: o! _; _# W9 F/ a  k; v5 H<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>- q: p, \. s/ ^5 H
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>) j, Y# Q% @4 Q* I$ q+ a% c. |' ~
<P ><FONT face="Times New Roman">}//while</FONT></P>
& s; @- Z+ K$ Z8 E<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>1 _* d2 z$ w1 {/ f
<P ><FONT face="Times New Roman">}//if</FONT></P>
5 z. ^5 F2 ~; Y: l<P ><FONT face="Times New Roman">return –1;</FONT></P>  S8 O' I2 k; q9 T5 N
<P ><FONT face="Times New Roman">}</FONT></P>6 k' R9 K! ~2 V7 c5 l- u* y+ \
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- P6 O  b" [. a
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
" {- Q7 J; n1 N+ Z# F5 Y3 v<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>5 H% C' C( _: D' V
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>" S- J7 G3 k  {0 R- S
<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>  O. {- R' n8 d% j' e
<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>: B, \7 G6 S$ A8 T0 ^* j9 r
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>7 \- W& e- ]2 d$ H8 U
<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>
0 {" U. R) y6 ^: k<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
+ h1 z1 ]6 I& \8 E" _! u% c9 v<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>
. a9 L; }# e) [# J1 h0 A<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>" v2 J* s0 b5 S6 g% y, n9 d
<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>6 h. E3 }- z( F, ~
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>) ^$ c3 W1 F3 I, E5 j  ]4 E. t
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
7 Q' Y% V) _5 p: B8 T- Y! z<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>1 c5 v9 B; ?& N0 K; j5 s% v3 M
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>& a3 d0 }; Y: Q# |* D
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
9 O- }. ?# b* v8 G6 e$ N9 i<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
) s/ n* S$ [5 S1 {<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 f0 j$ g4 u8 `" ?, U<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>
! Y6 b# Y4 H8 L0 n7 E  u, g( y<P >即:middle &gt; left成立。<o:p></o:p></P>* L2 S" V" K: U4 r& N" L2 N$ U# u
<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 s9 u- r0 v+ N! s! [! n$ W
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>
# x. c# J, ]% S9 M2 \<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
9 g; W4 f& m" W: ?1 i  N4 H* y<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
( z( C$ q  c/ A6 F! ^& T$ K<P >∴返回结果正确。<o:p></o:p></P>
& c+ y  M: o/ z5 m% z- K<P >(6)算法6是错误的。<o:p></o:p></P>9 p$ C* R$ Q% M. r7 O
<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>8 c# @5 d$ S0 T6 R. \- A
<P >left = middle + 1;<o:p></o:p></P>* a% d8 v* o. d, m3 {6 y2 @
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>( ^3 C4 E1 A- v: U3 p8 h; m
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>* D* V( h. z6 f8 H4 |
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>5 ~; S1 A% q8 X# c2 `0 A+ j
<P >(7)算法7是错误的。<o:p></o:p></P>
' |" C: I* F) e( D<P >在循环过程中,一旦出现<o:p></o:p></P>9 N  _" Q" i, S; Z+ C. M
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
, z- H" S3 `9 s$ e% e0 y% z<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 13:47 , Processed in 0.435399 second(s), 51 queries .

回顶部