[讨论]一道分治法的题目,仅供参考
<P ><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><P ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left <= right)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right) / 2;</FONT></P>
<P ><FONT face="Times New Roman"> if(x == a) return middle;</FONT></P>
<P ><FONT face="Times New Roman"> if(x > a) left = middle;</FONT></P>
<P ><FONT face="Times New Roman"> else right = middle;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left < right-1)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right) / 2;</FONT></P>
<P ><FONT face="Times New Roman"> if(x < a) right = middle;</FONT></P>
<P ><FONT face="Times New Roman"> else left = middle;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">if(x == a) return left;</FONT></P>
<P ><FONT face="Times New Roman">else return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left+1 != right)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right) / 2;</FONT></P>
<P ><FONT face="Times New Roman"> if(x >= a) left = middle;</FONT></P>
<P ><FONT face="Times New Roman"> else right = middle;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">if(x == a) return left;</FONT></P>
<P ><FONT face="Times New Roman">else return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> if(n > 0 && x >= a)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left < right)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right) / 2;</FONT></P>
<P ><FONT face="Times New Roman">if(x < a) right = middle - 1;</FONT></P>
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">if(x == a) return left;</FONT></P>
<P ><FONT face="Times New Roman">}//if</FONT></P>
<P ><FONT face="Times New Roman">return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> if(n > 0 && x >= a)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left < right)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right + 1) / 2;</FONT></P>
<P ><FONT face="Times New Roman">if(x < a) right = middle - 1;</FONT></P>
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">if(x == a) return left;</FONT></P>
<P ><FONT face="Times New Roman">}//if</FONT></P>
<P ><FONT face="Times New Roman">return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> if(n > 0 && x >= a)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left < right)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right + 1) / 2;</FONT></P>
<P ><FONT face="Times New Roman">if(x < a) right = middle - 1;</FONT></P>
<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">if(x == a) return left;</FONT></P>
<P ><FONT face="Times New Roman">}//if</FONT></P>
<P ><FONT face="Times New Roman">return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>
<P ><FONT face="Times New Roman">{</FONT></P>
<P ><FONT face="Times New Roman"> if(n > 0 && x >= a)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int left = 0, right = n-1;</FONT></P>
<P ><FONT face="Times New Roman"> while(left < right)</FONT></P>
<P ><FONT face="Times New Roman"> {</FONT></P>
<P ><FONT face="Times New Roman"> int middle = (left + right +1) / 2;</FONT></P>
<P ><FONT face="Times New Roman">if(x < a) right = middle;</FONT></P>
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
<P ><FONT face="Times New Roman">}//while</FONT></P>
<P ><FONT face="Times New Roman">if(x == a) return left;</FONT></P>
<P ><FONT face="Times New Roman">}//if</FONT></P>
<P ><FONT face="Times New Roman">return –1;</FONT></P>
<P ><FONT face="Times New Roman">}</FONT></P>
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
<P ><FONT face="Times New Roman">if(x > a) left = middle + 1;<o:p></o:p></FONT></P>
<P ><FONT face="Times New Roman"> else right = middle - 1;<o:p></o:p></FONT></P>
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
<P >当<FONT face="Times New Roman">n</FONT>≥<FONT face="Times New Roman">2</FONT>时,如果条件<FONT face="Times New Roman">x = a </FONT>且<FONT face="Times New Roman"> a </FONT>≠<FONT face="Times New Roman"> a</FONT>成立,则必将在某一步之后出现<FONT face="Times New Roman">x = a</FONT>,导致永远不会出现<FONT face="Times New Roman">x = a</FONT>的情形,算法最终在<FONT face="Times New Roman">x = a</FONT>时结束循环,导致错误地返回<FONT face="Times New Roman">-1</FONT>。<o:p></o:p></P>
<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
<P >原因:循环结束条件错误,应改为<FONT face="Times New Roman">left <= right</FONT>。每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改也不正确。<o:p></o:p></P>
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
<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>
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>
<P >如果在循环过程中出现<FONT face="Times New Roman">left = right – 1</FONT>情况,算法即进入死循环。例如<FONT face="Times New Roman"> x</FONT>≥a条件成立时,即必然进入死循环。<o:p></o:p></P>
<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
<P >当<FONT face="Times New Roman">n</FONT>≥<FONT face="Times New Roman">2</FONT>时,在循环结束前有<FONT face="Times New Roman">x</FONT>≥a且left < right,<o:p></o:p></P>
<P >∴<FONT face="Times New Roman">middle = (left + right + 1) / 2 = / 2 </FONT>≥ (2left + 2) / 2 = left + 1,<o:p></o:p></P>
<P >即:middle > left成立。<o:p></o:p></P>
<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>
<P >∴left < middle ≤ right恒成立。<o:p></o:p></P>
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a且x = a成立,否则x ≠a,即未找到x,<o:p></o:p></P>
<P >∴返回结果正确。<o:p></o:p></P>
<P >(6)算法6是错误的。<o:p></o:p></P>
<P >当执行到某次循环x = a成立时,再执行if 语句中的<o:p></o:p></P>
<P >left = middle + 1;<o:p></o:p></P>
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>
<P >当n = 2且x = a时即会出现这些情况。<o:p></o:p></P>
<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>
<P >(7)算法7是错误的。<o:p></o:p></P>
<P >在循环过程中,一旦出现<o:p></o:p></P>
<P >a ≤ x < a,则必进入死循环。<o:p></o:p></P>
<P >原因:right值的修改不正确。<o:p></o:p></P>
页:
[1]