﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-庄周梦蝶-随笔分类-数据结构与算法</title><link>http://www.blogjava.net/killme2008/category/20137.html</link><description>生活、程序、未来</description><language>zh-cn</language><lastBuildDate>Tue, 02 Nov 2010 07:47:52 GMT</lastBuildDate><pubDate>Tue, 02 Nov 2010 07:47:52 GMT</pubDate><ttl>60</ttl><item><title>一道面试题注记</title><link>http://www.blogjava.net/killme2008/archive/2010/10/28/336357.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 28 Oct 2010 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2010/10/28/336357.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/336357.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2010/10/28/336357.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/336357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/336357.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; javaeye的一个帖子介绍一道<a href="http://www.javaeye.com/topic/795101">面试题</a>，取数组的最大元素和前n个大元素，取最大元素很简单，遍历即可。取前N大元素，可以利用排序，最简单的实现：<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;findTopNValues(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;anyOldOrderValues,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Arrays.sort(anyOldOrderValues);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[n];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(anyOldOrderValues,&nbsp;anyOldOrderValues.length&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;n,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span></div>
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; Arrays.sort(int[])使用的是快排，平均的时间复杂度是O( n lg(n))，在一般情况下已经足够好。那么有没有平均情况下O(n)复杂度的算法？这个还是有的，这道题目其实是选择算法的变形，选择一个数组中的第n大元素，可以采用类似快排的方式划分数组，然后只要在一个子段做递归查找就可以，平均状况下可以做到O(n)的时间复杂度，对于这道题来说稍微变形下算法即可解决：<span style="color: #000000;"><br />
<br />
</span>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;求数组的前n个元素<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;anyOldOrderValues<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;n<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;findTopNValues(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;anyOldOrderValues,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[n];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;findTopNValues(anyOldOrderValues,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;anyOldOrderValues.length&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;n,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n,&nbsp;result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;findTopNValues(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;a,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;p,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;r,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;result)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;全部取到，直接返回</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;只剩一个元素，拷贝到目标数组</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;r)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(a,&nbsp;p,&nbsp;result,&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;i,&nbsp;i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;len&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;r&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;p&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;len&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;IllegalArgumentException();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;if&nbsp;(len&nbsp;&lt;&nbsp;7)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Arrays.sort(a,&nbsp;p,&nbsp;r+1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;System.arraycopy(a,&nbsp;r&nbsp;-&nbsp;i+1&nbsp;,&nbsp;result,&nbsp;n&nbsp;-&nbsp;i,&nbsp;i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;划分</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;q&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;medPartition(a,&nbsp;p,&nbsp;r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;计算右子段长度</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;k&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;r&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;q&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;右子段长度恰好等于i</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;k)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;拷贝右子段到结果数组，返回</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(a,&nbsp;q,&nbsp;result,&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;i,&nbsp;i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(k&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;右子段比i长，递归到右子段求前i个元素</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;findTopNValues(a,&nbsp;q&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;r,&nbsp;i,&nbsp;n,&nbsp;result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;右子段比i短，拷贝右子段到结果数组，递归左子段求前i-k个元素</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(a,&nbsp;q,&nbsp;result,&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;i,&nbsp;k);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;findTopNValues(a,&nbsp;p,&nbsp;q&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;k,&nbsp;n,&nbsp;result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;medPartition(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x[],&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;p,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;r)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;len&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;r&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;p&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;(len&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(len&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">7</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;l&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;r;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(len&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">40</span><span style="color: #000000;">)&nbsp;{&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Big&nbsp;arrays,&nbsp;pseudomedian&nbsp;of&nbsp;9</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;s&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;len&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">8</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;med3(x,&nbsp;l,&nbsp;l&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;s,&nbsp;l&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;med3(x,&nbsp;m&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;s,&nbsp;m,&nbsp;m&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;s);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;med3(x,&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;s,&nbsp;n&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;s,&nbsp;n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;med3(x,&nbsp;l,&nbsp;m,&nbsp;n);&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Mid-size,&nbsp;med&nbsp;of&nbsp;3</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(m&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;r)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;x[m];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x[m]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;x[r];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x[r]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;partition(x,&nbsp;p,&nbsp;r);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;med3(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x[],&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;c)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;x[a]&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;x[b]&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;(x[b]&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;x[c]&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;b&nbsp;:&nbsp;x[a]&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;x[c]&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;c&nbsp;:&nbsp;a)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;x[b]&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;x[c]&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;b&nbsp;:&nbsp;x[a]&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;x[c]&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;c&nbsp;:&nbsp;a;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;swap(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;a,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;a[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;a[j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;partition(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a[],&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;p,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;r)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;a[r];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;m&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;r;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">do</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(j</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">p</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">a[j]&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">do</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(a[m]&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(j&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;m)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(a,&nbsp;m,&nbsp;j);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(a,&nbsp;r,&nbsp;j&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span></div>
&nbsp;选择算法还有最坏情况下O(n)复杂度的实现，有兴趣可以读算法导论和<a href="http://en.wikipedia.org/wiki/Selection_algorithm">维基百科</a>。题外，我测试了下这两个实现，在我的机器上大概有2倍多的差距，还是很明显。<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/336357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2010-10-28 10:53 <a href="http://www.blogjava.net/killme2008/archive/2010/10/28/336357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LinkedList的局限</title><link>http://www.blogjava.net/killme2008/archive/2010/09/16/332168.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 16 Sep 2010 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2010/09/16/332168.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/332168.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2010/09/16/332168.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/332168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/332168.html</trackback:ping><description><![CDATA[<br />
&nbsp;&nbsp;&nbsp; java.util.LinkedList是双向链表，这个大家都知道，比如Java的基础面试题喜欢问ArrayList和LinkedList的区别，在什么场景下用。大家都会说LinkedList随机增删多的场景比较合适，而ArrayList的随机访问多的场景比较合适。更进一步，我有时候会问，LinkedList.remove(Object)方法的时间复杂度是什么？有的人回答对了，有的人回答错了。回答错的应该是没有读过源码。<br />
<br />
&nbsp;&nbsp;&nbsp; 理论上说，双向链表的删除的时间复杂度是O(1)，你只需要将要删除的节点的前节点和后节点相连，然后将要删除的节点的前节点和后节点置为null即可，<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000;">//</span><span style="color: #008000;">伪代码</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">node.prev.next</span><span style="color: #000000;">=</span><span style="color: #000000;">node.next;<br />
node.next.prev</span><span style="color: #000000;">=</span><span style="color: #000000;">node.prev;<br />
node.prev</span><span style="color: #000000;">=</span><span style="color: #000000;">node.next</span><span style="color: #000000;">=</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;</span></div>
<br />
这个操作的时间复杂度可以认为是O(1)级别的。但是LinkedList的实现是一个通用的数据结构，因此没有暴露内部的节点Entry对象，remove(Object)传入的Object其实是节点存储的value，这里还需要一个查找过程：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;remove(Object&nbsp;o)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(o</span><span style="color: #000000;">==</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">E</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;header.next;&nbsp;e&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;header;&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.next)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(e.element</span><span style="color: #000000;">==</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remove(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找节点Entry</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">E</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;header.next;&nbsp;e&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;header;&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.next)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(o.equals(e.element))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">删除节点</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remove(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
<br />
&nbsp;&nbsp;&nbsp; 删除节点的操作就是刚才伪代码描述的：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;E&nbsp;remove(Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">E</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.element;<br />
&nbsp;&nbsp;&nbsp;&nbsp;e.previous.next&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;e.next.previous&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.previous;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.next&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.previous&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.element&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;size</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;modCount</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
&nbsp;&nbsp;&nbsp; 因此，显然，LinkedList.remove(Object)方法的时间复杂度是O(n)+O(1)，结果仍然是O(n)的时间复杂度,而非推测的O(1)复杂度。最坏情况下要删除的元素是最后一个，你都要比较N-1次才能找到要删除的元素。<br />
<br />
&nbsp;&nbsp;&nbsp; 既然如此，说LinkedList适合随机删减有个前提，链表的大小不能太大，如果链表元素非常多，调用remove(Object)去删除一个元素的效率肯定有影响，一个简单测试，插入100万数据，随机删除1000个元素：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;List</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Integer</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;list&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> LinkedList</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Integer</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1000000</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;count;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Random&nbsp;rand</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Random();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;start</span><span style="color: #000000;">=</span><span style="color: #000000;">System.nanoTime();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">1000</span><span style="color: #000000;">;i</span><span style="color: #000000;">++</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">这里要强制转型为Integer，否则调用的是remove(int)</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.remove((Integer)rand.nextInt(count));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println((System.nanoTime()</span><span style="color: #000000;">-</span><span style="color: #000000;">start)</span><span style="color: #000000;">/</span><span style="color: #000000;">Math.pow(</span><span style="color: #000000;">10</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">9</span><span style="color: #000000;">));</span></div>
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 在我的机器上耗时近9.5秒，删除1000个元素耗时9.5秒，是不是很恐怖？注意到上面的注释，产生的随机数强制转为Integer对象，否则调用的是remove(int)方法，而非remove(Object)。如果我们调用remove(int)根据索引来删除:<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">1000</span><span style="color: #000000;">;i</span><span style="color: #000000;">++</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.remove(rand.nextInt(list.size()</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
&nbsp;&nbsp;&nbsp; 随机数范围要递减，防止数组越界，换成remove(int)效率提高不少，但是仍然需要2.2秒左右（包括了随机数产生开销）。这是因为remove(int)的实现很有技巧，它首先判断索引位置在链表的前半部分还是后半部分，如果是前半部分则从head往前查找，如果在后半部分，则从head往后查找（LinkedList的实现是一个环）：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">E</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;header;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(index&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;(size&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">前一半，往前找</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;index;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">后一半，往后找</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;size;&nbsp;i&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;index;&nbsp;i</span><span style="color: #000000;">--</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e.previous; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 最坏情况下要删除的节点在中点左右，查找的次数仍然达到n/2次，但是注意到这里没有比较的开销，并且比remove(Object)最坏情况下n次查找还是好很多。<br />
<br />
&nbsp;&nbsp;&nbsp; 总结下，LinkedList的两个remove方法，remove(Object)和remove(int)的时间复杂度都是O(n)，在链表元素很多并且没有索引可用的情况下，LinkedList也并不适合做随机增删元素。在对性能特别敏感的场景下，还是需要自己实现专用的双向链表结构，真正实现O(1)级别的随机增删。更进一步，jdk5引入的ConcurrentLinkedQueue是一个非阻塞的线程安全的双向队列实现，同样有本文提到的问题，有兴趣可以测试一下在大量元素情况下的并发随机增删，效率跟自己实现的特定类型的线程安全的链表差距是惊人的。<br />
<br />
&nbsp;&nbsp;&nbsp; 题外，ArrayList比LinkedList更不适合随机增删的原因是多了一个数组移动的动作，假设你删除的元素在m，那么除了要查找m次之外，还需要往前移动n-m-1个元素。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/332168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2010-09-16 13:51 <a href="http://www.blogjava.net/killme2008/archive/2010/09/16/332168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>快速排序及优化</title><link>http://www.blogjava.net/killme2008/archive/2010/09/08/quicksort_optimized.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 08 Sep 2010 11:10:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2010/09/08/quicksort_optimized.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/331404.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2010/09/08/quicksort_optimized.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/331404.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/331404.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; update：更正选择中数的描述，在7到39之间的数组大小选择median-of-three来选择pivot，大小等于7的数组则直接使用中数作为pivot。&nbsp;&nbsp;&nbsp; quicksort可以说是应用最广泛的排序算法之一，它的基本思想是分治法，选择一个pivot(中轴点），将小于pivot放在左边，将大于pivot放在右边，针对...&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2010/09/08/quicksort_optimized.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/331404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2010-09-08 19:10 <a href="http://www.blogjava.net/killme2008/archive/2010/09/08/quicksort_optimized.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>缓存的分代</title><link>http://www.blogjava.net/killme2008/archive/2010/06/05/322822.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 05 Jun 2010 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2010/06/05/322822.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/322822.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2010/06/05/322822.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/322822.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/322822.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; Java的垃圾收集算法是分代的，因为根据2/8原则，80%的Java对象都是速生速灭的，因此将Java Heap划分为new和old，对两个区域采用不同的垃圾回收算法，在new代存活下来的对象转移到old区，这样一来大大提高了Java GC的效率。<br />
&nbsp;&nbsp;&nbsp; 类似分代的思想在很多地方可以用到，分代的本质是根据对象生命周期的不同做区别处理，而不是采取一刀切的方式来提高系统的处理效率。推而广之，比如缓存的使用，现在很多web应用都采用了类似memcached这样的缓存挡在数据库前面分担负载，那么你可以将memcached理解成new代，而数据库是old代。memcached中存储的是查询的热点数据，新鲜火热，但是易失，并且在数据更新的时候被移除；而数据库保存了所有的数据，当缓存没有命中的时候才去查询数据库并存储到缓存。new和old这只是简单的二代划分，事实上现在越来越多的系统是多级缓存，页面缓存、memcached缓存、JVM内部缓存、查询缓存等等直到数据库，从web页面到后端是一个越来越old的过程，缓存对象持续的生命周期逐渐增长直到persist状态。<br />
&nbsp;&nbsp;&nbsp; 具体到JVM内部缓存，我们通常使用LRU算法来实现一个安全有限的缓存，如直接继承LinkedHashMap将可以实现一个简单的LRUMap。基于内存使用上的考虑，我们会给LRUMap设定一个最大的capacity，当数据量超过这个capacity的时候将最近最少访问的元素移除来容纳新的元素。这样处理产生的问题是这个capactity不能设置得太大，因为怕内存不够用，但是不够大的结果可能是命中率没有那么高（跟你的场景相关），那么如何在保存内存安全的前提下更进一步缓存更多的对象呢？答案也是分代。LRUMap默认存储的都是对象的强引用，我们知道Java还有其他3种引用类：soft,weak和<span id="ArticleContent1_ArticleContent1_lblContent"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span lang="EN-US">phantom</span></span></span>。其中Soft引用是在jvm内存不够的时候进行回收，weak引用是在垃圾回收碰到的时候会被回收，显然weak-&gt;soft-&gt;strong三类引用的生命周期可以划分为3个代，我们将可以实现一个可以容纳更多对象的LRUMap：LRUMap设置两个阀值，一个是强引用的最大阀值，这个不能太大，一个是软引用的最大数目，当超过第一个阀值的时候，不是将LRU替换出来的对象移除，而是替代转换为软引用存储；如果软引用的数目也超过阀值，那么可以将软引用这个Map里的对象LRU替换成Weak引用存储或者简单移除。处理元素查询的时候，多了一个步骤，在查询强引用未果的情况下，需要再去查询软引用集合，不过都是O(1)复杂度的查询，不会成为明显的瓶颈。通过将缓存对象分代，我们实现了容难更多缓存对象的目标，大部分对象以强引用的形式存储，被LRU替换出去最近最少访问的元素以软引用存储，它们在内存不够的时候被垃圾回收，保证了内存使用上的安全性。我们在系统中采用了类似这样的缓存，缓存的命中率有了明显的提高。<br />
&nbsp;&nbsp;&nbsp; 题目是《缓存的分代》，其实谈的是分代这种常见的设计或者说技巧，在需要处理大量对象的场景中，不采用一刀切的方式，而是根据对象的特点进行适当的分代处理，带来的效率提升可能是惊人的。<br />
<br />
&nbsp;&nbsp;&nbsp; PS.关于这个<a href="http://www.blogjava.net/killme2008/archive/2010/06/03/322630.html">招聘</a>罗嗦两句，我是这个小组的成员，有人质疑我的目的是为了赚推荐费，这个不能说没有，不过主要目的还是招人，我们很缺人。那么多要求可以归结为一句话：我们找Java基础良好、对并发通信有丰富实践经验、写代码相对靠谱、为人相对靠谱的人。那些要求并非硬性，如果你觉的合适，尽管投简历，谢谢。我们小组做的东西我认为还是有价值的，也很有挑战，淘宝内部的很多应用都在使用，如果你希望你做的产品被成千上万的人每天使用，欢迎加入。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
&nbsp;&nbsp;&nbsp; <br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/322822.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2010-06-05 10:13 <a href="http://www.blogjava.net/killme2008/archive/2010/06/05/322822.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Project euler 18题解答</title><link>http://www.blogjava.net/killme2008/archive/2009/09/27/296582.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 26 Sep 2009 18:52:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2009/09/27/296582.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/296582.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2009/09/27/296582.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/296582.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/296582.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; &nbsp;<span style="font-family: 'Trebuchet MS',sans-serif; font-size: 16px;">By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
<p style="text-align: center; font-family: 'courier new'; font-size: 12pt;"><span style="color: #ff0000;"><strong>3</strong></span><br />
<span style="color: #ff0000;"><strong>7</strong></span>&nbsp;4<br />
2&nbsp;<span style="color: #ff0000;"><strong>4</strong></span>&nbsp;6<br />
8 5&nbsp;<span style="color: #ff0000;"><strong>9</strong></span>&nbsp;3</p>
<p>That is, 3 + 7 + 4 + 9 = 23.</p>
<p>Find the maximum total from top to bottom of the triangle below:</p>
<p style="text-align: center; font-family: 'courier new';">75<br />
95 64<br />
17 47 82<br />
18 35 87 10<br />
20 04 82 47 65<br />
19 01 23 75 03 34<br />
88 02 77 73 07 63 67<br />
99 65 04 28 06 16 70 92<br />
41 41 26 56 83 40 80 70 33<br />
41 48 72 33 47 32 37 16 94 29<br />
53 71 44 65 25 43 91 52 97 51 14<br />
70 11 33 28 77 73 17 78 39 68 17 57<br />
91 71 52 38 17 14 91 43 58 50 27 29 48<br />
63 66 04 68 89 53 67 30 73 16 69 87 40 31<br />
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23</p>
<p class="info" style="font-weight: normal; font-size: 13px;"><strong>NOTE:</strong>&nbsp;As there are only 16384 routes, it is possible to solve this problem by trying every route. However,&nbsp;<a href="http://projecteuler.net/index.php?section=problems&amp;id=67" style="text-decoration: none; color: #676c9c;">Problem 67</a>, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)</p>
<p class="info" style="font-weight: normal; font-size: 13px;">&nbsp;&nbsp; &nbsp;最简单的方法就是穷举，从根节点出发，每个节点都有两个分叉，到达底部的路径有估计有2的指数级的数目（有会算的朋友请留言，我的组合数学都还给老师了），不过这道题显然是符合动态规划的特征，往下递增一层的某个节点的最佳结果f[i][j]肯定是上一层两个入口节点对应的最佳结果的最大值，也就是f[i-1][j]或者f[i-1][j+1]，递归的边界就是定点f[0][0]=75。因此我的解答如下，考虑了金字塔边界的情况，数据按照金字塔型存储在numbers.txt中，</p>
<p class="info" style="font-weight: normal; font-size: 13px;">
</p>
<div style="padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.BufferedReader;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.InputStreamReader;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Euler18Problem&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;maxSun(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;a,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;rows,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;cols)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;结果列表</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;f&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[</span><span style="color: #000000;">15</span><span style="color: #000000;">][</span><span style="color: #000000;">15</span><span style="color: #000000;">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;路径，用于输出计算路径</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;path&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[</span><span style="color: #000000;">15</span><span style="color: #000000;">][</span><span style="color: #000000;">15</span><span style="color: #000000;">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;递归边界</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[</span><span style="color: #000000;">0</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;a[</span><span style="color: #000000;">0</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[</span><span style="color: #000000;">0</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;递推</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;rows;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;决策</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;j&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;col;&nbsp;j</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;左边界</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(j&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;f[i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][j]&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;a[i][j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(j&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;col)&nbsp;{&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;右边界</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;f[i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][j&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;a[i][j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;处于中间位置</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(f[i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][j]&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;f[i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][j&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">])&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;f[i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][j&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;a[i][j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;j&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;f[i&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">][j]&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;a[i][j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[i][j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;j;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;求出结果</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;cols;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(f[</span><span style="color: #000000;">14</span><span style="color: #000000;">][i]&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;result)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;f[</span><span style="color: #000000;">14</span><span style="color: #000000;">][i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;输出路径</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">row=14,col=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;col&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,value=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;a[</span><span style="color: #000000;">14</span><span style="color: #000000;">][col]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;rows&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">--</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;path[i][col];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">row=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,col=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;col&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,value=</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;a[i][col]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(result);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;rows&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">15</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;cols&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">15</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[][]&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[rows][cols];<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedReader&nbsp;reader&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BufferedReader(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;InputStreamReader(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Euler18Problem.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">.getResourceAsStream(</span><span style="color: #000000;">"</span><span style="color: #000000;">/numbers.txt</span><span style="color: #000000;">"</span><span style="color: #000000;">)));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;line&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;row&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;((line&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;reader.readLine())&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">line.trim().equals(</span><span style="color: #000000;">""</span><span style="color: #000000;">))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;numbers&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;line.split(</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;numbers.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[row][i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Integer.parseInt(numbers[i]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.close();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxSun(a,&nbsp;rows,&nbsp;cols);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
&nbsp;&nbsp;&nbsp;&nbsp; 执行结果如下，包括了路径输出：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">row</span><span style="color: #000000;">=</span><span style="color: #000000;">14</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">9</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">93</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">13</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">8</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">73</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">12</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">7</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">43</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">11</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">6</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">17</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">10</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">5</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">43</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">9</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">4</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">47</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">8</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">3</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">56</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">7</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">3</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">28</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">6</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">3</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">73</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">5</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">23</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">4</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">82</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">3</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">87</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">47</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">95</span><span style="color: #000000;"><br />
row</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">,col</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">,value</span><span style="color: #000000;">=</span><span style="color: #000000;">75</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">1074</span><span style="color: #000000;"><br />
</span></div>
<br />
&nbsp;&nbsp;&nbsp; ps.并非我闲的蛋疼在半夜做题，只是被我儿子折腾的无法睡觉了，崩溃。<br /><img src ="http://www.blogjava.net/killme2008/aggbug/296582.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2009-09-27 02:52 <a href="http://www.blogjava.net/killme2008/archive/2009/09/27/296582.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>os的进程调度（读书笔记）</title><link>http://www.blogjava.net/killme2008/archive/2009/06/28/284459.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sun, 28 Jun 2009 05:28:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2009/06/28/284459.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/284459.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2009/06/28/284459.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/284459.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/284459.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 在多进程、多线程并发的环境里，从概念上看，有多个进程或者多个线程在同时执行，具体到单个CPU级别，实际上任何时刻只能有一个进程或者线程处于执行状态；因此OS需要决定哪个进程执行，哪些进程等待，也就是进程的调度。<br />
一、调度的目标<br />
1、首先要区分程序使用CPU的三种模式：IO密集型、计算密集型和平衡型。对于IO密集型程序来说，响应时间非常重要；对于CPU密集型来说，CPU的周转时间就比较重要；对于平衡型程序来说，响应和周转之间的平衡是最重要的。<br />
2、CPU的调度就是要达到极小化平均响应时间、极大化系统吞吐率、保持系统各个功能部件均处于繁忙状态和提供某种公平的机制。<br />
3、对于实时系统来说，调度的目标就是要达到截止时间前完成所应该完成的任务和提供性能的可预测性。<br />
<br />
二、调度算法<br />
<br />
1、FCFS（First come first serve)，或者称为FIFO算法，先来先处理。这个算法的优点是简单，实现容易，并且似乎公平；缺点在于短的任务有可能变的非常慢，因为其前面的任务占用很长时间，造成了平均响应时间非常慢。<br />
<br />
2、时间片轮询算法，这是对FIFO算法的改进，目的是改善短程序（运行时间短）的响应时间，其方法就是周期性地进行进程切换。这个算法的关键点在于时间片的选择，时间片过大，那么轮转就越接近FIFO，如果太小，进程切换的开销大于执行程序的开销，从而降低了系统效率。因此选择合适的时间片就非常重要。选择时间片的两个需要考虑的因素：一次进程切换所使用的系统消耗以及我们能接受的整个系统消耗、系统运行的进程数。<br />
&nbsp;&nbsp;&nbsp; 时间片轮询看上起非常公平，并且响应时间非常好，然而时间片轮转并不能保证系统的响应时间总是比FIFO短，这很大程度上取决于时间片大小的选择，以及这个大小与进程运行时间的相互关系。<br />
<br />
3、STCF算法（Short time to complete first)，顾名思义就是短任务优先算法。这种算法的核心就是所有的程序都有一个优先级，短任务的优先级比长任务的高，而OS总是安排优先级高的进程运行。<br />
&nbsp;&nbsp;&nbsp; STCF又分为两类：非抢占式和抢占式。非抢占式STCF就是让已经在CPU上运行的程序执行到结束或者阻塞，然后在所有的就绪进程中选择执行时间最短的来执行；而抢占式STCF就不是这样，在每进来一个新的进程时，就对所有进程（包括正在CPU上执行的进程）进行检查，谁的执行时间短，就运行谁。<br />
<br />
&nbsp;&nbsp;&nbsp; STCF总是能提供最优的响应时间，然而它也有缺点，第一可能造成长任务的程序无法得到CPU时间而饥饿，因为OS总是优先执行短任务；其次，关键问题在于我们怎么知道程序的运行时间，怎么预测某个进程需要的执行时间？通常有两个办法：使用启发式方法估算（例如根据程序大小估算），或者将程序执行一遍后记录其所用的CPU时间，在以后的执行过程中就可以根据这个测量数据来进行STCF调度。<br />
<br />
4、优先级调度，STCF遇到的问题是长任务的程序可能饥饿，那么优先级调度算法可以通过给长任务的进程更高的优先级来解决这个问题；优先级调度遇到的问题可能是短任务的进程饥饿，这个可以通过动态调整优先级来解决。实际上动态调整优先级（称为权值）+时间片轮询的策略正是linux的进程调度策略之一的 SCHED_OTHER分时调度策略,它的调度过程如下：<br />
<br />
（1）创建任务指定采用分时调度策略，并指定优先级nice值(-20~19)。<br />
<br />
（2）将根据每个任务的nice值确定在cpu上的执行时间(counter)。<br />
<br />
（3）如果没有等待资源，则将该任务加入到就绪队列中。<br />
<br />
（4）调度程序遍历就绪队列中的任务，通过对每个任务动态优先级的计算(counter+20-nice)结果，选择计算结果最大的一个去运行，当这个时间片用完后(counter减至0)或者主动放弃cpu时，该任务将被放在就绪队列末尾(时间片用完)或等待队列(因等待资源而放弃cpu)中。<br />
<br />
（5）此时调度程序重复上面计算过程，转到第4步。<br />
<br />
（6）当调度程序发现所有就绪任务计算所得的权值都为不大于0时，重复第2步。<br />
<br />
linux还有两个实时进程的调度策略：FIFO和RR,实时进程会立即抢占非实时进程。<br />
<br />
5、显然，没有什么调度算法是毫无缺点的，因此现代OS通常都会采用混合调度算法。例如将不同的进程分为几个大类，每个大类有不同的优先级，不同大类的进程的调度取决于大类的优先级，同一个大类的进程采用时间片轮询来保证公平性。<br />
<br />
6、其他调度算法，保证调度算法保证每个进程享用的CPU时间完全一样；彩票调度算法是一种概率调度算法，通过给进程&#8220;发彩票&#8221;的多少，来赋予不同进程不同的调用时间，彩票调度算法的优点是非常灵活，如果你给短任务发更多&#8220;彩票&#8221;，那么就类似STCF调度，如果给每个进程一样多的&#8220;彩票&#8221;，那么就类似保证调度；用户公平调度算法，是按照每个用户，而不是按照每个进程来进行公平分配CPU时间，这是为了防止贪婪用户启用了过多进程导致系统效率降低甚至停顿。<br />
<br />
7、实时系统的调度算法，实时系统需要考虑每个具体任务的响应时间必须符合要求，在截止时间前完成。<br />
（1）EDF调度算法，就是最早截止任务优先（Earliest deadline first)算法，也就是让最早截止的任务先做。当新的任务过来时，如果它的截止时间更靠前，那么就让新任务抢占正在执行的任务。EDF算法其实是贪心算法的一种体现。如果一组任务可以被调度（也就是所有任务的截止时间在理论上都可以得到满足），那么EDF可以满足。如果一批任务不能全部满足（全部在各自的截止时间前完成），那EDF满足的任务数最多，这就是它最优的体现。EDF其实就是抢占式的STCF，只不过将程序的执行时间换成了截止时间。EDF的缺点在于需要对每个任务的截止时间做计算并动态调整优先级，并且抢占任务也需要消耗系统资源。因此它的实际效果比理论效果差一点。<br />
<br />
（2）RMS调度算法，EDF是动态调度算法，而RMS（rate monotonic scheduling)算法是一种静态最优算法；该算法在进行调度前先计算出所有任务的优先级，然后按照计算出来的优先级进行调度，任务执行中间既不接收新任务，也不进行优先级调整或者CPU抢占。因此它的优点是系统消耗小，缺点就是不灵活了。对于RMS算法，关键点在于判断一个任务组是否能被调度，这里有一个定律，如果一个系统的所有任务的CPU利用率都低于ln2，那么这些任务的截止时间均可以得到满足，ln2约等于0.693147，也就是此时系统还剩下有30%的CPU时间。这个证明是Liu和Kayland在1973年给出的。<br />
<br />
三、优先级反转<br />
1、什么是优先级反转？<br />
&nbsp;&nbsp;&nbsp; 优先级反转是指一个低优先级的任务持有一个被高优先级任务所需要的共享资源。高优先任务由于因资源缺乏而处于受阻状态，一直等到低优先级任务释放资源为止。而低优先级获得的CPU时间少，如果此时有优先级处于两者之间的任务，并且不需要那个共享资源，则该中优先级的任务反而超过这两个任务而获得CPU时间。如果高优先级等待资源时不是阻塞等待，而是忙循环，则可能永远无法获得资源，因为此时低优先级进程无法与高优先级进程争夺CPU时间，从而无法执行，进而无法释放资源，造成的后果就是高优先级任务无法获得资源而继续推进。<br />
<br />
2、解决方案：<br />
（1）设置优先级上限，给临界区一个高优先级，进入临界区的进程都将获得这个高优先级，如果其他试图进入临界区的进程的优先级都低于这个高优先级，那么优先级反转就不会发生。<br />
<br />
（2）优先级继承，当一个高优先级进程等待一个低优先级进程持有的资源时，低优先级进程将暂时获得高优先级进程的优先级别，在释放共享资源后，低优先级进程回到原来的优先级别。嵌入式系统VxWorks就是采用这种策略。<br />
&nbsp;&nbsp;&nbsp; 这里还有一个八卦，1997年的美国的火星探测器（使用的就是vxworks)就遇到一个优先级反转问题引起的故障。简单说下，火星探测器有一个信息总线，有一个高优先级的总线任务负责总线数据的存取，访问总线都需要通过一个互斥锁（共享资源出现了）；还有一个低优先级的，运行不是很频繁的气象搜集任务，它需要对总线写数据，也就同样需要访问互斥锁；最后还有一个中优先级的通信任务，它的运行时间比较长。平常这个系统运行毫无问题，但是有一天，在气象任务获得互斥锁往总线写数据的时候，一个中断发生导致通信任务被调度就绪，通信任务抢占了低优先级的气象任务，而无巧不成书的是，此时高优先级的总线任务正在等待气象任务写完数据归还互斥锁，但是由于通信任务抢占了CPU并且运行时间比较长，导致气象任务得不到CPU时间也无法释放互斥锁，本来是高优先级的总线任务也无法执行，总线任务无法及时执行的后果被探路者认为是一个严重错误，最后就是整个系统被重启。Vxworks允许优先级继承，然而遗憾的工程师们将这个选项关闭了。<br />
<br />
（3）第三种方法就是使用中断禁止，通过禁止中断来保护临界区，采用此种策略的系统只有两种优先级：可抢占优先级和中断禁止优先级。前者为一般进程运行时的优先级，后者为运行于临界区的优先级。火星探路者正是由于在临界区中运行的气象任务被中断发生的通信任务所抢占才导致故障，如果有临界区的禁止中断保护，此一问题也不会发生。<br />
&nbsp; <br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/284459.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2009-06-28 13:28 <a href="http://www.blogjava.net/killme2008/archive/2009/06/28/284459.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util.HashMap源码要点浅析</title><link>http://www.blogjava.net/killme2008/archive/2009/04/15/265721.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 15 Apr 2009 04:33:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2009/04/15/265721.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/265721.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2009/04/15/265721.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/265721.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/265721.html</trackback:ping><description><![CDATA[1、散列表要解决的一个问题就是散列值的冲突问题，通常是两种方法：链表法和开放地址法。链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位；开放地址法是通过一个探测算法，当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。java.util.HashMap采用的链表法的方式，链表是单向链表，因此在删除过程中要自己维持prev节点，我想不采用双向链表是从节省空间考虑。一个典型的查找过程：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(Entry</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">K,V</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;e&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;table[indexFor(hash,&nbsp;table.length)];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;</span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;e.next)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;k;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(e.hash&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;hash&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((k&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;e.key)&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;key&nbsp;</span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);">&nbsp;(key&nbsp;</span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;key.equals(k))))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;e;<br />
&nbsp;}</span></div>
&nbsp;&nbsp; HashMap采用链表法而不是开放地址法，猜想可能的原因是从实用角度出发，对空间和时间效率做出的折中选择。采用开放地址法，无论是线性探测或者二次探测都可能造成群集现象，而双重散列会要求散列表的装填程度比较低的情况下会有比较好的查找效率，容易造成空间的浪费。<br />
<br />
2、什么是负载因子？负载因子a定义为<br />
&nbsp;&nbsp;&nbsp;&nbsp; a=散列表的实际元素数目(n)/ 散列表的容量(m)<br />
<br />
负载因子衡量的是一个散列表的空间的使用程度，负载因子越大表示散列表的装填程度越高，反之愈小。对于使用链表法的散列表来说，查找一个元素的平均时间是 O(1+a)，因此如果负载因子越大，对空间的利用更充分，然而后果是查找效率的降低；如果负载因子太小，那么散列表的数据将过于稀疏，对空间造成严重浪费。<br />
<br />
回到HashMap的实现，HashMap中的loadFactor其实定义的就是该map对象允许的最大的负载因子，如果超过这个系数将重新resize。这个是通过threshold字段来判断，看threshold的计算：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">threshold&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">)(capacity&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;loadFactor);</span></div>
<br />
结合上面的负载因子的定义公式可知，threshold就是在此loadFactor和capacity对应下允许的最大元素数目，超过这个数目就重新resize，以降低实际的负载因子。默认的的负载因子0.75是对空间和时间效率的一个平衡选择。注意到的一点是resize的规模是现有 capacity的两倍：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(size</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;=</span><span style="color: rgb(0, 0, 0);">&nbsp;threshold)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resize(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;table.length);</span></div>
&nbsp;<br />
3、可能你也注意到了，java.util.HashMap对key的hash值多做了一步处理，而不是直接使用hashCode：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;hash(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;h)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h&nbsp;</span><span style="color: rgb(0, 0, 0);">^=</span><span style="color: rgb(0, 0, 0);">&nbsp;(h&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">20</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">&nbsp;(h&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">12</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;h&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">&nbsp;(h&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">&nbsp;(h&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;}</span></div>
<br />
这个处理的原因在于HashMap的容量总是采用2的p次幂，而取index（槽位）的方法是<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;indexFor(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;h,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;length)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;h&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;(length</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;}<br />
</span></div>
<br />
这一运算等价于对length取模，也就是<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h % 2^p<br />
返回的将是h的p个最低位组成的数字，我们假设hash输入是符合简单一致散列，然而这一假设并不能推论出hash的p个最低位也会符合简单一致散列，也许h的这p个最低位相同的几率很大，那么冲突的几率就非常大了。优秀的散列函数应该需要考虑所有的位。<br />
<br />
因此为了防止这些&#8220;坏&#8221;的散列函数造成效率的降低，HashMap预先对hash值做了处理以考虑到所有的位，根据注释也可以知道。这个处理我看不懂，留待高人解释，也许来自于某本算法书也不一定。<br />
<br />
4、我们知道java.util.HashMap不是线程安全的，因此如果在使用迭代器的过程中有其他线程修改了map，那么将抛出ConcurrentModificationException，这就是所谓fail-fast策略（速错），这一策略在源码中的实现是通过 modCount域，modCount顾名思义就是修改次数，对HashMap内容的修改都将增加这个值，那么在迭代器初始化过程中会将这个值赋给迭代器的expectedModCount，<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);"><br />
&nbsp;HashIterator()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expectedModCount&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;modCount;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(size&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)&nbsp;{&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;advance&nbsp;to&nbsp;first&nbsp;entry</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entry[]&nbsp;t&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;table;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">&nbsp;(index&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;t.length&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;(next&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;t[index</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">])&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span></div>
<br />
在迭代过程中，判断modCount跟expectedModCount是否相等，如果不相等就表示已经有其他线程修改了map<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);">&nbsp;Entry</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">K,V</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;nextEntry()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(modCount&nbsp;</span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);">&nbsp;expectedModCount)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ConcurrentModificationException();<br />
</span></div>
&nbsp;注意到modCount声明为volatile，保证线程之间修改的可见性。<br />
&nbsp;<br />
<br />
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/265721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2009-04-15 12:33 <a href="http://www.blogjava.net/killme2008/archive/2009/04/15/265721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sicp4.1.1-4.1.5节部分习题尝试解答(update)</title><link>http://www.blogjava.net/killme2008/archive/2008/06/01/205155.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sun, 01 Jun 2008 07:51:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/06/01/205155.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/205155.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/06/01/205155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/205155.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/205155.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 当将用scheme写的scheme求值器跑起来的时候，你不觉的兴奋是不可能的，真的太酷了，太magic了。<br />
习题4.2，如果将application？判断放在define?判断之前，那么求值(define x 3)将把define当作一般的procedure应用于参数x和3，可是define是特殊的语法形式，而非一般过程，导致出错。<br />
习题4.4，我的解答，eval增加两个判断：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;((and</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exp)<br />
&nbsp;&nbsp;&nbsp;(eval</span><span style="color: #000000;">-</span><span style="color: #000000;">and&nbsp;(and</span><span style="color: #000000;">-</span><span style="color: #000000;">exps&nbsp;exp)&nbsp;env))<br />
&nbsp;((or</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exp)<br />
&nbsp;&nbsp;&nbsp;(eval</span><span style="color: #000000;">-</span><span style="color: #000000;">or&nbsp;(or</span><span style="color: #000000;">-</span><span style="color: #000000;">exps&nbsp;exp)&nbsp;env))</span></div>
实现谓词和各自的过程：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define&nbsp;(and</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exp)&nbsp;<br />
&nbsp;&nbsp;(tagged</span><span style="color: #000000;">-</span><span style="color: #000000;">list</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exp&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">and))</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">(define&nbsp;(and</span><span style="color: #000000;">-</span><span style="color: #000000;">exps&nbsp;exp)<br />
&nbsp;&nbsp;(cdr&nbsp;exp))<br />
(define&nbsp;(eval</span><span style="color: #000000;">-</span><span style="color: #000000;">and&nbsp;exps&nbsp;env)<br />
&nbsp;&nbsp;(cond&nbsp;((</span><span style="color: #0000ff;">null</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exps)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">true)</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((result&nbsp;(eval&nbsp;(car&nbsp;exps)&nbsp;env)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(not&nbsp;result)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(eval</span><span style="color: #000000;">-</span><span style="color: #000000;">and&nbsp;(cdr&nbsp;exps)&nbsp;env))))))<br />
(define&nbsp;(or</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exp)<br />
&nbsp;&nbsp;(tagged</span><span style="color: #000000;">-</span><span style="color: #000000;">list</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exp&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">or))</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">(define&nbsp;(or</span><span style="color: #000000;">-</span><span style="color: #000000;">exps&nbsp;exp)&nbsp;(cdr&nbsp;exp))<br />
(define&nbsp;(eval</span><span style="color: #000000;">-</span><span style="color: #000000;">or&nbsp;exps&nbsp;env)<br />
&nbsp;&nbsp;(cond&nbsp;((</span><span style="color: #0000ff;">null</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;exps)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">false)</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((result&nbsp;(eval&nbsp;(car&nbsp;exps)&nbsp;env)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;result<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(eval</span><span style="color: #000000;">-</span><span style="color: #000000;">or&nbsp;(cdr&nbsp;exps)&nbsp;env))))))</span></div>
<br />
如果用宏实现就简单了：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define</span><span style="color: #000000;">-</span><span style="color: #000000;">syntax&nbsp;and<br />
&nbsp; (syntax</span><span style="color: #000000;">-</span><span style="color: #000000;">rules&nbsp;()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((_)&nbsp;#t)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((_&nbsp;e)&nbsp;e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((_&nbsp;e1&nbsp;e2&nbsp;e3&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;e1&nbsp;(and&nbsp;e2&nbsp;e3&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)&nbsp;#f))))<br />
(define</span><span style="color: #000000;">-</span><span style="color: #000000;">syntax&nbsp;or<br />
&nbsp;&nbsp; (syntax</span><span style="color: #000000;">-</span><span style="color: #000000;">rules&nbsp;()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((_)&nbsp;#f)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((_&nbsp;e)&nbsp;e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((_&nbsp;e1&nbsp;e2&nbsp;e3&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (let&nbsp;((t&nbsp;e1))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;t&nbsp;t&nbsp;(or&nbsp;e2&nbsp;e3&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />))))))</span></div>
<br />
习题4.5，cond的扩展形式，也不难，在else子句之外增加个判断，是否带有=&gt;符号，修改expand-clauses过程：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define (cond-extended-clauses? clause)<br />
&nbsp; (and (&gt; (length clause) 2) (eq? (cadr clause) '=&gt;)))<br />
(define (extended-cond-test clause)<br />
&nbsp; (car clause))<br />
(define (extended-cond-recipient clause)<br />
&nbsp; (caddr clause)<br />
(define&nbsp;(expand</span><span style="color: #000000;">-</span><span style="color: #000000;">clauses&nbsp;clauses)<br />
&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">null</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;clauses)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">false</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((first&nbsp;(car&nbsp;clauses))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;(cdr&nbsp;clauses)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;((cond</span><span style="color: #000000;">-</span><span style="color: #0000ff;">else</span><span style="color: #000000;">-</span><span style="color: #000000;">clauses</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;first)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">null</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;rest)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(sequence</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">exp&nbsp;(cond</span><span style="color: #000000;">-</span><span style="color: #000000;">actions&nbsp;first))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(error&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">else&nbsp;clause&nbsp;is&nbsp;not&nbsp;LAST</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;clauses)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((cond</span><span style="color: #000000;">-</span><span style="color: #000000;">extended</span><span style="color: #000000;">-</span><span style="color: #000000;">clauses</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;first)&nbsp; ;判断是否扩展形式<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #0000ff;">if</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(extended</span><span style="color: #000000;">-</span><span style="color: #000000;">cond</span><span style="color: #000000;">-</span><span style="color: #000000;">test&nbsp;first)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(extended</span><span style="color: #000000;">-</span><span style="color: #000000;">cond</span><span style="color: #000000;">-</span><span style="color: #000000;">recipient&nbsp;first)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(extended</span><span style="color: #000000;">-</span><span style="color: #000000;">cond</span><span style="color: #000000;">-</span><span style="color: #000000;">test&nbsp;first))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(expand</span><span style="color: #000000;">-</span><span style="color: #000000;">clauses&nbsp;rest)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(cond</span><span style="color: #000000;">-</span><span style="color: #000000;">predicate&nbsp;first)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(sequence</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">exp&nbsp;(cond</span><span style="color: #000000;">-</span><span style="color: #000000;">actions&nbsp;first))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(expand</span><span style="color: #000000;">-</span><span style="color: #000000;">clauses&nbsp;rest)))))))</span></div>
<br />
习题4.6，let如果用宏定义，类似这样：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define</span><span style="color: #000000;">-</span><span style="color: #000000;">syntax&nbsp;let<br />
&nbsp;&nbsp;(syntax</span><span style="color: #000000;">-</span><span style="color: #000000;">rules&nbsp;()<br />
&nbsp;&nbsp;&nbsp;&nbsp;((_&nbsp;((x&nbsp;v)&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)&nbsp;e1&nbsp;e2&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #0000ff;">lambda</span><span style="color: #000000;">&nbsp;(x&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)&nbsp;e1&nbsp;e2&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)&nbsp;v&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />))))</span></div>
求值器扩展，实现let-&gt;combination过程：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define&nbsp;(let?&nbsp;exp)<br />
&nbsp;&nbsp;(tagged</span><span style="color: #000000;">-</span><span style="color: #000000;">list?&nbsp;exp&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">let))</span><span style="color: #800000;"><br />
</span><span style="color: #000000;">(define&nbsp;(let</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">combination&nbsp;exp)<br />
&nbsp;&nbsp;(let&nbsp;((vars&nbsp;(map&nbsp;car&nbsp;(cadr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vals&nbsp;(map&nbsp;cadr&nbsp;(cadr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(body&nbsp;(caddr&nbsp;exp)))<br />
&nbsp;&nbsp;(cons&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #0000ff;">lambda</span><span style="color: #000000;">&nbsp;vars&nbsp;(list&nbsp;body))&nbsp;vals)))</span></div>
我们做的仅仅是syntax transform，将let转成对应的lambda形式。<br />
<br />
习题4.7，这里的关键在于let*-&gt;netsted-lets要递归调用，从let*的宏定义可以看出：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define</span><span style="color: #000000;">-</span><span style="color: #000000;">syntax&nbsp;let</span><span style="color: #000000;">*</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(syntax</span><span style="color: #000000;">-</span><span style="color: #000000;">rules()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((_&nbsp;((var1&nbsp;val1))&nbsp;e1&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((var1&nbsp;val1))&nbsp;e1&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((_&nbsp;((var1&nbsp;val1)&nbsp;(var2&nbsp;val2)&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)&nbsp;e1&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((var1&nbsp;val1))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;((var2&nbsp;val2)&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e1&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />)))))</span></div>
那么，let*-&gt;nested-lets可以定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define&nbsp;(let</span><span style="color: #000000;">*</span><span style="color: #000000;">?&nbsp;exp)<br />
&nbsp;&nbsp;(tagged</span><span style="color: #000000;">-</span><span style="color: #000000;">list?&nbsp;exp&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">let*))</span><span style="color: #800000;"><br />
</span><span style="color: #000000;">(define&nbsp;(let</span><span style="color: #000000;">*-&gt;</span><span style="color: #000000;">nested</span><span style="color: #000000;">-</span><span style="color: #000000;">lets&nbsp;exp)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((pairs&nbsp;(cadr&nbsp;exp))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(body&nbsp;(caddr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;(cdr&nbsp;pairs))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">let&nbsp;pairs&nbsp;body)</span><span style="color: #800000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">let&nbsp;(list&nbsp;(car&nbsp;pairs))&nbsp;(let*-&gt;nested-lets&nbsp;(list&nbsp;</span><span style="color: #800000;">'</span><span style="color: #000000;">let</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;(cdr&nbsp;pairs)&nbsp;body))))))</span></div>
测试一下：<br />
(let* ((x 1) (y (+ x 3))) (+ x y)) =》5<br />
<br />
习题4.8，命名let，修改let-&gt;combination过程，判断cadr是pair还是symbol，如果是前者，那就是一般的let，如果是symbol就是命名let语句，那么需要定义一个名为(cadr exp)的过程放在body里，注意，我们是在做语法转换，因此，这个定义也应该描述成符号，定义一个make-define过程来生成define语句：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">define&nbsp;var&nbsp;parameters&nbsp;body)<br />
&nbsp;&nbsp;(list&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">define&nbsp;(cons&nbsp;var&nbsp;parameters)&nbsp;body))</span></div>
然后修改let-&gt;combination过程，如上所述：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">(define&nbsp;(let</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">combination&nbsp;exp)<br />
&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(symbol?&nbsp;(cadr&nbsp;exp))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((var&nbsp;(cadr&nbsp;exp))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vars&nbsp;(map&nbsp;car&nbsp;(caddr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vals&nbsp;(map&nbsp;cadr&nbsp;(caddr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pairs&nbsp;(caddr&nbsp;exp))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(body&nbsp;(cadddr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #0000ff;">lambda</span><span style="color: #000000;">&nbsp;vars&nbsp;(list&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">define&nbsp;var&nbsp;vars&nbsp;body)&nbsp;body))&nbsp;vals))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((vars&nbsp;(map&nbsp;car&nbsp;(cadr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(vals&nbsp;(map&nbsp;cadr&nbsp;(cadr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(body&nbsp;(caddr&nbsp;exp)))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #0000ff;">lambda</span><span style="color: #000000;">&nbsp;vars&nbsp;(list&nbsp;body))&nbsp;vals))))</span></div>
<br />
<br />
习题4.1.4，原生的map过程接受的procedure，是以scheme内在数据结构表示的procedure，而在我们的求值器中，procedure的内在数据结构取决于我们，与原生的结构不同，导致原生的map无法接受自制求值器的procedure，如果map也以求值器中的结构定义，那么就没有这个问题。因此，本质上的困难就在于两个求值器对procedure的数据结构表示的不同。<br />
<br />
习题4.1.5，著名的图灵停机问题，先是假设存在halts?过程可以正确地判断任何过程p和对象a是否p对a终止，定义了try过程：<br />
(define (try p)<br />
&nbsp;&nbsp; (if (halts? p p)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (run-forever)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'halted))<br />
当执行(try try),如果这个过程可终止，那么(halts? try try)应该返回false，也就是try过程对try不会终止，这与一开始的假设矛盾；如果这个过程将无穷运行下去，那么(halts? try try)应该返回true，也就是try对try终止，这也与(try try)将无穷运行的假设矛盾。因此，可以推论出，我们不可能写出一个过程halts?，使它能正确地判断任何过程p和对象a是否p对a终止。<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/205155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-06-01 15:51 <a href="http://www.blogjava.net/killme2008/archive/2008/06/01/205155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Rope来高效处理长字符串</title><link>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 05 May 2008 10:41:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/198532.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/198532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/198532.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 前段时间看了这篇文章《<a href="http://www.ibm.com/developerworks/cn/java/j-ropes/index.html">Ropes：理论与实践</a>》。这两天为了提高工作中某个系统对外接口的效率，才认真学习了一番。本质上Ropes是将字符串表示为一棵二叉树，特别适用于长字符串的处理，貌似c++ STL库中也有这么个实现。具体实现和原理还是看这篇<a href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">paper</a>。《<a href="http://www.ibm.com/developerworks/cn/java/j-ropes/index.html">Ropes：理论与实践</a>》一文中给出的测试数据相当惊人，Ropes比之String和StringBuffer在append,insert,delete等操作上的效率都有一个数量级以上的差距。跑下作者给出的测试程序，其实在测试的字符串不是很长的情况下，这个差距并没有那么大，这也从侧面说明了Rope的应用范围：即只有在大量修改大型字符串的应用程序中才能看到明显的性能提升。那么是否可以用Rope替代StringBuffer做append生成字符串（比如我要的生成xml)。作者也说啦：<br />
&nbsp; &#8220;由于 <code>Rope</code> 的附加性能通常比 <code>StringBuffer</code> 好，这时使用 rope
是否有意义呢？答案还是否。不论何时将输入的数据组合在一起形成格式化输出时，最漂亮最有效的方法是使用模板引擎（例如 StringTemplate
或 FreeMarker）。这种方法不仅能干净地将表示标记与代码分开，而且模板只进行一次编译（通常编译为 JVM
字节码），以后可以重用，从而使它们拥有极佳的性能特征。&#8221;<br />
<br />
&nbsp;&nbsp;&nbsp; 我用Rope for java替代了StringBuffer做XML生成，效率提升在5%-30%左右，xml字符串不是很长，这个提升显然有限，也带来了不必要的复杂度。因此最后还是用Velocity模板引擎来生成XML，测试的结果效率并没有多少改善，但是显然更容易维护和开发了。回到Rope的话题，我用Ruby实现了个版本，Rubyforge上有一个Rope的实现，但是看了源码，与paper所述算法有点差异，因此照着Rope for java也实现了一个<a href="http://code.google.com/p/rope4r/">Rope4r</a>。测试的结果证明在长字符串的累积操作上，Rope4r的append比之String的+=性能可以快上3倍左右，而如果采用String的&lt;&lt;操作，不是immutable的，当然是最快了；比较郁闷的是slice和insert操作都比String的慢上几倍，因为Ruby的String、Array的内建对象都是直接用c写成并做了优化的，我猜测原因在这。<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/198532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-05-05 18:41 <a href="http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>善用表驱动法</title><link>http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 17 Apr 2008 11:50:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/193852.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/193852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/193852.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 最近碰到个需求，计算游戏得分的规则，类似这样：<br />
<table class="MsoNormalTable" style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">游戏人数</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第一名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.2pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第二名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第三名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #dfdfdf none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal"><span style="font-family: 宋体; color: red;">第四名获得赌注</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">二人</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></strong></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">100%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">0%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-family: 宋体; color: red;">—</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-family: 宋体; color: red;">—</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">二人</span></strong><span style="font-size: 9pt; font-family: 宋体; color: red;">（出现</span><span style="font-size: 9pt; color: red;" lang="EN-US">2</span><span style="font-size: 9pt; font-family: 宋体; color: red;">个第</span><span style="font-size: 9pt; color: red;" lang="EN-US">1</span><span style="font-size: 9pt; font-family: 宋体; color: red;">名时）</span><strong><span style="color: red;" lang="EN-US"><o:p></o:p></span></strong></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">50%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">50%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">三人</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></strong></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">70%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">30%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.25pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">0%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-family: 宋体; color: red;">—</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">三人</span></strong><span style="font-family: 宋体; color: red;">（</span><span style="font-size: 9pt; font-family: 宋体; color: red;">出现</span><span style="font-size: 9pt; color: red;" lang="EN-US">3</span><span style="font-size: 9pt; font-family: 宋体; color: red;">个第</span><span style="font-size: 9pt; color: red;" lang="EN-US">1</span><span style="font-size: 9pt; font-family: 宋体; color: red;">名时</span><span style="font-family: 宋体; color: red;">）</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">33.3333%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">33.3333%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.25pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">33.3333%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal"><strong><span style="font-family: 宋体; color: red;">三人</span></strong><span style="font-size: 9pt; color: red;" lang="EN-US">(</span><span style="font-size: 9pt; font-family: 宋体; color: red;">出现</span><span style="font-size: 9pt; color: red;" lang="EN-US">2</span><span style="font-size: 9pt; font-family: 宋体; color: red;">个第</span><span style="font-size: 9pt; color: red;" lang="EN-US">1</span><span style="font-size: 9pt; font-family: 宋体; color: red;">名时</span><span style="font-size: 9pt; color: red;" lang="EN-US">)</span><span style="color: red;" lang="EN-US"><o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">50%</span><span style="font-family: 宋体; color: red;">&#215;</span><span style="color: red;" lang="EN-US">2<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; width: 85.2pt;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US">0%<o:p></o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
            <td style="padding: 0cm 5.4pt; background: #b4b4b4 none repeat scroll 0%; width: 85.25pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" valign="top" width="114">
            <p class="MsoNormal" style="text-align: center;" align="center"><span style="color: red;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
            </td>
        </tr>
    </tbody>
</table>
......<br />
......<br />
&nbsp;&nbsp;&nbsp; 这些奖励规则没有什么规律，随着人数增多，就越发复杂了，并且业务人员可能随时改变这些规则。<br />
&nbsp;&nbsp;&nbsp; 显然，奖励规则可以采用策略模式，定义策略接口，根据游戏人数定义不同的规则，本质上就是利用动态的多态调用。可以想见，还是少不了复杂的case...when语句，以及繁多的代码。恰好最近读《unix编程艺术》和《代码大全2》，两者都提到一个结论：人类阅读复杂数据结构远比复杂的控制流程容易，或者说数据驱动开发是非常有价值的。《代码大全2》声称这个是表驱动法。因此，这个奖励系数的计算，能否转化成一个查表过程呢？注意到，在游戏中，名次是根据个人的积分在所有玩家中的排位来决定，大概会有这么个排序的玩家积分数组[100,50,3]，这个数组表示3个玩家，第一名100分，第二名50分，第三名才3分。依据规则，第一名的奖励系数就是0.7，第二名就是0.3。我想到类似这样的数组其实都有个形式表示它们的内置结构，比如[100,50,3]数组的&#8220;结构&#8221;是"111"，代表3个位置都有一个人。将"111"作为关键码去查表不就OK了？<br />
&nbsp;&nbsp;&nbsp; 将每个排好序的积分数组解码为这样的关键码，然后去查预先写好的奖励系数表，这个奖励系数表大概类似：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;@@award_rate_hash</span><span style="color: #000000;">=</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">11</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">1</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">20</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">}<br />
&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">111</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">300</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.33</span><span style="color: #000000;">},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">201</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">120</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">1</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0}<br />
&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1111</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.65</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.30</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.05</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">4000</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.25</span><span style="color: #000000;">},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">3001</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.33</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1300</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">1</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">2020</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.5</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1201</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.15</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">1120</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span><span style="color: #800000;">"</span><span style="color: #800000;">2011</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.35</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">4</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;}</span></div>
&nbsp;&nbsp;&nbsp; 一个三级hash表，首先根据玩家人数查到特定的系数表，比如要查3个玩家、积分数组是[100,50,3]的奖励系数表就是<span style="color: #000000;">&nbsp; @@award_rate_hash</span><span style="color: #000000;">[:"3"]，然后积分数组</span>[100,50,3]<span style="color: #000000;">解码为:"111"，继续查，如此规则的奖励系数表就是</span><span style="color: #000000;">@@award_rate_hash</span><span style="color: #000000;">[:"3"][</span><span style="color: #000000;">:"111"]——也就是</span><span style="color: #000000;"> </span><span style="color: #000000;">{:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">2</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.3</span><span style="color: #000000;">,:</span><span style="color: #800000;">"</span><span style="color: #800000;">3</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0}，那么查积分是100的玩家系数就是</span><span style="color: #000000;">@@award_rate_hash</span><span style="color: #000000;">[:"3"][</span><span style="color: #000000;">:"111"][</span>([100,50,3].index(100)+1<span style="color: #000000;">).to_s.to_sym]，也就是</span><span style="color: #000000;">:</span><span style="color: #800000;">"</span><span style="color: #800000;">1</span><span style="color: #800000;">"</span><span style="color: #000000;">=&gt;</span><span style="color: #000000;">0.7</span><span style="color: #000000;">。</span>[100,50,3].index(100)+1<span style="color: #000000;">就是积分100的玩家在数组中的名次(即1)，也就是:"1"指向的结果0.7</span>。其他玩家的查表过程与此类似，不细说了。<br />
&nbsp;&nbsp;&nbsp; 这样，我们所有的奖励规则就是维护这么一张hash表，这个表看起来复杂，其实完全可以自动生成，让业务人员来提供样例数据，解码样例数据并生成这个表是很简单的事情。积分数组的&#8220;解码&#8221;，我给一个Ruby版本：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">#</span><span style="color: #008000;">解码数组为字符串关键码</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> decode_array(array)<br />
&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000;">=</span><span style="color: #000000;">array.size<br />
&nbsp;&nbsp;&nbsp;&nbsp;trace_list</span><span style="color: #000000;">=</span><span style="color: #000000;">[]<br />
&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="color: #000000;">=</span><span style="color: #000000;">[]<br />
&nbsp;&nbsp;&nbsp;&nbsp;len.times&nbsp;do&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">time</span><span style="color: #000000;">|</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result[time]</span><span style="color: #000000;">=</span><span style="color: #000000;">0&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace_list[time]</span><span style="color: #000000;">=</span><span style="color: #000000;">false<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;array.each_with_index&nbsp;do&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">item,index</span><span style="color: #000000;">|</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result[index]</span><span style="color: #000000;">=</span><span style="color: #000000;">count_times(array,trace_list,index,len)<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result.join(</span><span style="color: #800000;">''</span><span style="color: #000000;">).to_sym<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> count_times(array,trace_list,index,len)<br />
&nbsp;&nbsp;&nbsp;&nbsp;item</span><span style="color: #000000;">=</span><span style="color: #000000;">array[index]<br />
&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="color: #000000;">=</span><span style="color: #000000;">0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(index..len).each&nbsp;do&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">i</span><span style="color: #000000;">|</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;array[i]</span><span style="color: #000000;">==</span><span style="color: #000000;">item&nbsp;</span><span style="color: #0000ff;">and</span><span style="color: #000000;">&nbsp;!trace_list[i]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="color: #000000;">+=</span><span style="color: #000000;">1</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace_list[i]</span><span style="color: #000000;">=</span><span style="color: #000000;">true<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result<br />
&nbsp;&nbsp;end</span></div>
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/193852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-04-17 19:50 <a href="http://www.blogjava.net/killme2008/archive/2008/04/17/193852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于binary search</title><link>http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 02 Apr 2008 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/190285.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/190285.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/190285.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 编程珠玑Column 4关于binary search的部分相当精彩，<font face="Courier New">1946年就有人发表binary search，但直到1962第一个正确运行的算法才写出来。尽管算法描述看起来简单明了，但是要写的正确却是有许多地方要仔细考虑。作者着重强调的是对程序正确性的分析方法，仔细分析方法的</font><font face="Courier New">pre-condition, invariant,和post-condition。</font>g9老大翻译过Joshua Bloch在google blog上的文章《<a href="http://blog.csdn.net/g9yuayon/archive/2006/06/04/772382.aspx">号外，号外，几乎所有的binary search和mergsort都有错</a>》，原文在<a href="http://feeds.feedburner.com/~r/blogspot/gJZg/~3/144582870/extra-extra-read-all-about-it-nearly.html">这里</a>。今天看了下原文，有更新，对于求中值索引的c/c++方法原文仍然是有错的，本来是这样：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;((unsigned)&nbsp;(low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;high))&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">。</span></div>
<br />
但是在c99标准中，对于两个signed数值之和，如果溢出结果是未定义的(undefined)，也就是说与编译器实现相关。上面的代码应该修改为：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">mid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;((unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;(unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)high))&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;</span></div>
<br />
我查了下jdk6的java.util.Arrays的源码，joshua bloch说的这个问题已经解决，现在的binary search如下：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Like&nbsp;public&nbsp;version,&nbsp;but&nbsp;without&nbsp;range&nbsp;checks.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;binarySearch0(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;a,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;fromIndex,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;toIndex,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;low&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fromIndex;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;high&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;toIndex&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(low&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;high)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;high)&nbsp;</span><span style="color: #000000;">&gt;&gt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;midVal&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;a[mid];<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(midVal&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;low&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(midVal&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;high&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;mid&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;mid;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;key&nbsp;found</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">(low&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;key&nbsp;not&nbsp;found.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
&nbsp;&nbsp;&nbsp; 如原文所讨论的，采用了&gt;&gt;&gt;操作符替代除以2<img src ="http://www.blogjava.net/killme2008/aggbug/190285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-04-02 10:08 <a href="http://www.blogjava.net/killme2008/archive/2008/04/02/190285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>位图排序</title><link>http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 07 Jan 2008 07:30:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/173362.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/173362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/173362.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 《编程珠玑》第一章第一题就相当的精彩，做个笔记。题目如下：<br />
输入:&nbsp;&nbsp; 一个包含n个正整数的文件，每个正整数小于n,n等于10的7次方（一千万）。并且文件内的正整数没有重复和关联数据。<br />
<br />
输出:&nbsp; 输入整数的升序排列<br />
&nbsp;<br />
约束： 限制在1M左右内存，充足的磁盘空间<br />
<br />
&nbsp;&nbsp;&nbsp; 假设整数占32位，1M内存可以存储大概250000个整数，第一个方法就是采用基于磁盘的合并排序算法，第二个办法就是将0-9999999切割成40个区间，分40次扫描（10000000/250000)，每次读入250000个在一个区间的整数，并在内存中使用快速排序。书中提出的第三个解决办法是采用bitmap（或者称为bit vector）来表示所有数据集合（注意到条件，数据没有重复），这样就可以一次性将数据读入内存，减少了扫描次数。算法的伪代码如下：<br />
阶段1：初始化一个空集合<br />
&nbsp;&nbsp;&nbsp;&nbsp; for i=[0,n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bit[i]=0;<br />
阶段2：读入数据i，并设置bit[i]=1<br />
&nbsp;&nbsp;&nbsp; for each i in the input file<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bit[i]=1;<br />
阶段3：输出排序的结果<br />
&nbsp;&nbsp; for i=[0,n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if bit[i]==1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; write i on the output file<br />
<br />
这个算法的时间复杂度在O(n)，用c语言写的版本可以在10秒内完成任务！c语言的源码在该书主页上有，这里给一个java的测试版，加上我的理解注释：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;"><br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;*&nbsp;Created&nbsp;by&nbsp;IntelliJ&nbsp;IDEA.<br />
&nbsp;*&nbsp;User: zhuangxd<br />
&nbsp;*&nbsp;Date:&nbsp;2008-1-7<br />
&nbsp;*&nbsp;Time:&nbsp;14:30:44<br />
&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BitSortTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;BITSPERWORD&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">32</span><span style="color: #000000;">;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">整数位数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;SHIFT&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">5</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;MASK&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0x1F</span><span style="color: #000000;">;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">5位遮蔽 0B11111</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;N&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">10000000</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">用int数组来模拟位数组，总计(1&nbsp;+&nbsp;N&nbsp;/&nbsp;BITSPERWORD)*BITSPERWORD位，足以容纳N</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;N&nbsp;</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;BITSPERWORD)];<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bitsort(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]{</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">100</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">10000</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">9999</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">4567</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">78902</span><span style="color: #000000;">});<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;bitsort(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">[]&nbsp;array)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;N;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clr(i);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">位数组所有位清0</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;array.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set(array[i]);&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">阶段2</span><br />
<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;N;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(test(i))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">置a[i&gt;&gt;SHIFT]的第(i&nbsp;&amp;&nbsp;MASK)位为1，</span><span style="color: #008000;">也就是位数组的第i位为1</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;set(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;SHIFT]&nbsp;</span><span style="color: #000000;">|=</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">置a[i&gt;&gt;SHIFT]的第(i&nbsp;&amp;&nbsp;MASK)位为0,也就是位数组的第i位为0</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;clr(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;SHIFT]&nbsp;</span><span style="color: #000000;">&amp;=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">测试位数组的第i位是否为1</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;test(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(a[i&nbsp;</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;SHIFT]&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK)))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;MASK));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/173362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-01-07 15:30 <a href="http://www.blogjava.net/killme2008/archive/2008/01/07/173362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单LRU算法实现缓存-update2</title><link>http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 29 Sep 2007 09:49:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/149645.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/149645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/149645.html</trackback:ping><description><![CDATA[update1:第二个实现，读操作不必要采用独占锁，缓存显然是读多于写，读的时候一开始用独占锁是考虑到要递增计数和更新时间戳要加锁，不过这两个变量都是采用原子变量，因此也不必采用独占锁，修改为读写锁。<br />
update2:一个错误，老是写错关键字啊，<span style="color: #000000;">LRUCache的</span><span style="color: #000000;">maxCapacity应该声明为volatile，而不是transient。</span><br />
&nbsp;&nbsp;  <br />
&nbsp;&nbsp; 最简单的LRU算法实现，就是利用jdk的LinkedHashMap，覆写其中的removeEldestEntry(Map.Entry)方法即可，如下所示：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.ArrayList;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Collection;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.LinkedHashMap;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.Lock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReentrantLock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Map;<br />
<br />
<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;*&nbsp;类说明：利用LinkedHashMap实现简单的缓存，&nbsp;必须实现removeEldestEntry方法，具体参见JDK文档<br />
&nbsp;*&nbsp;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@author</span><span style="color: #008000;">&nbsp;dennis<br />
&nbsp;*&nbsp;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;K&gt;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;V&gt;<br />
&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;LRULinkedHashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;LinkedHashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxCapacity;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">float</span><span style="color: #000000;">&nbsp;DEFAULT_LOAD_FACTOR&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0.75f</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Lock&nbsp;lock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ReentrantLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;LRULinkedHashMap(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxCapacity)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">(maxCapacity,&nbsp;DEFAULT_LOAD_FACTOR,&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.maxCapacity&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;maxCapacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;removeEldestEntry(java.util.Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;eldest)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;size()&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;maxCapacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;containsKey(Object&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.containsKey(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;get(Object&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;put(K&nbsp;key,&nbsp;V&nbsp;value)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.put(key,&nbsp;value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;size()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;clear()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.clear();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Collection</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;getAll()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ArrayList</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">(</span><span style="color: #0000ff;">super</span><span style="color: #000000;">.entrySet());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
&nbsp;&nbsp;&nbsp; 如果你去看LinkedHashMap的源码可知，LRU算法是通过双向链表来实现，当某个位置被命中，通过调整链表的指向将该位置调整到头位置，新加入的内容直接放在链表头，如此一来，最近被命中的内容就向链表头移动，需要替换时，链表最后的位置就是最近最少使用的位置。<br />
&nbsp;&nbsp;&nbsp; LRU算法还可以通过计数来实现，缓存存储的位置附带一个计数器，当命中时将计数器加1，替换时就查找计数最小的位置并替换，结合访问时间戳来实现。这种算法比较适合缓存数据量较小的场景，显然，遍历查找计数最小位置的时间复杂度为O(n)。我实现了一个，结合了访问时间戳，当最小计数大于MINI_ACESS时(这个参数的调整对命中率有较大影响），就移除最久没有被访问的项：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;net.rubyeye.codelib.util.concurrency.cache;<br />
<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.Serializable;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.ArrayList;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Collection;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.HashMap;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Iterator;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Map;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Set;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.atomic.AtomicInteger;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.atomic.AtomicLong;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.Lock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReadWriteLock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReentrantLock;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.concurrent.locks.ReentrantReadWriteLock;<br />
<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;*&nbsp;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@author</span><span style="color: #008000;">&nbsp;dennis&nbsp;类说明：当缓存数目不多时，才用缓存计数的传统LRU算法<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;K&gt;<br />
&nbsp;*&nbsp;</span><span style="color: #808080;">@param</span><span style="color: #008000;">&nbsp;&lt;V&gt;<br />
&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;LRUCache</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;DEFAULT_CAPACITY&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">100</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;map;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;ReadWriteLock&nbsp;lock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ReentrantReadWriteLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Lock&nbsp;readLock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lock.readLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Lock&nbsp;writeLock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lock.writeLock();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;"> </span><span style="color: #0000ff;">volatile</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxCapacity;&nbsp; //保持可见性<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;MINI_ACCESS&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">5</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;LRUCache()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">(DEFAULT_CAPACITY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;LRUCache(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;capacity)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(capacity&nbsp;</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;RuntimeException(</span><span style="color: #000000;">"</span><span style="color: #000000;">缓存容量不得小于0</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.maxCapacity&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;capacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.map&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(maxCapacity);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;ContainsKey(K&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.map.containsKey(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;put(K&nbsp;key,&nbsp;V&nbsp;value)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;((map.size()&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;maxCapacity&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">map.containsKey(key))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;System.out.println("开始");</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;entries&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.map.entrySet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeRencentlyLeastAccess(entries);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;new_value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ValueEntry(value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;old_value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.put(key,&nbsp;new_value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(old_value&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_value.count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;old_value.count;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;old_value.value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;移除最近最少访问<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;removeRencentlyLeastAccess(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;entries)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;最小使用次数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;least&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;访问时间最早</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;earliest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K&nbsp;toBeRemovedByCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K&nbsp;toBeRemovedByTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterator</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;it&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;entries.iterator();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(it.hasNext())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;least&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;earliest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().lastAccess.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(it.hasNext())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;ValueEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry.getValue().count.get()&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;least)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;least&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry.getValue().lastAccess.get()&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;earliest)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;earliest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getValue().count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBeRemovedByTime&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.getKey();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;System.out.println("remove:"&nbsp;+&nbsp;toBeRemoved);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果最少使用次数大于MINI_ACCESS，那么移除访问时间最早的项(也就是最久没有被访问的项）</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(least&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;MINI_ACCESS)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.remove(toBeRemovedByTime);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.remove(toBeRemovedByCount);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;V&nbsp;get(K&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;V&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;更新访问时间戳</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;valueEntry.updateLastAccess();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;更新访问次数</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;valueEntry.count.incrementAndGet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;valueEntry.value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;clear()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.clear();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;size()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;map.size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;getCount(K&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValueEntry&nbsp;valueEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.get(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(valueEntry&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;valueEntry.count.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Collection</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;getAll()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.lock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;keys&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;map.keySet();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;tmp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(K&nbsp;key&nbsp;:&nbsp;keys)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp.put(key,&nbsp;map.get(key).value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ArrayList</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Map.Entry</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">K,&nbsp;V</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">(tmp.entrySet());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLock.unlock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ValueEntry&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;V&nbsp;value;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;AtomicLong&nbsp;count;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;AtomicLong&nbsp;lastAccess;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ValueEntry(V&nbsp;value)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;AtomicLong(</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastAccess&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;AtomicLong(System.nanoTime());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;updateLastAccess()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.lastAccess.set(System.nanoTime());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--></div>
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/149645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-09-29 17:49 <a href="http://www.blogjava.net/killme2008/archive/2007/09/29/149645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模仿st_table写的StTable类</title><link>http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 18 Sep 2007 11:28:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/146234.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/146234.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/146234.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; update1:添加了remove,removeAll()方法以及getSize()方法&nbsp;&nbsp;&nbsp; update2:添加了keySet()方法用于迭代 &nbsp;  &nbsp;&nbsp;&nbsp;update3:经过测试，StTable类在存储Integer类型key时,put的速度比HashMap快了接近3倍，而...&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/146234.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-09-18 19:28 <a href="http://www.blogjava.net/killme2008/archive/2007/09/18/146234.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>scheme实现huffman编码的完整代码</title><link>http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 23 Jul 2007 00:56:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/131788.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/131788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/131788.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 来自sicp的完整代码，包括书中给出的代码以及习题，实现了huffman树的生成、解码、编码过程，总共67行代码，同样的代码有空用java、ruby改写下，看看会有什么不同。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;symbol&nbsp;weight)<br>&nbsp;&nbsp;(list&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">leaf&nbsp;symbol&nbsp;weight))</span><span style="color: #800000;"><br></span><span style="color: #000000;">(define&nbsp;(leaf?&nbsp;object)<br>&nbsp;&nbsp;(eq?&nbsp;(car&nbsp;object)&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">leaf))</span><span style="color: #800000;"><br></span><span style="color: #000000;">(define&nbsp;(symbol</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;x)&nbsp;(cadr&nbsp;x))<br>(define&nbsp;(weight</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;x)&nbsp;(caddr&nbsp;x))<br>;合并最低权重的两个节点<br>(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">code</span><span style="color: #000000;">-</span><span style="color: #000000;">tree&nbsp;left&nbsp;right)<br>&nbsp;&nbsp;(list&nbsp;left&nbsp;right&nbsp;(append&nbsp;(symbols&nbsp;left)&nbsp;(symbols&nbsp;right))&nbsp;(</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;(weight&nbsp;left)&nbsp;(weight&nbsp;right))))<br>(define&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;tree)&nbsp;(car&nbsp;tree))<br>(define&nbsp;(right</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;tree)&nbsp;(cadr&nbsp;tree))<br>(define&nbsp;(symbols&nbsp;tree)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(symbol</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;tree))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(caddr&nbsp;tree)))<br>(define&nbsp;(weight&nbsp;tree)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(weight</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cadddr&nbsp;tree)))<br>;解码<br>(define&nbsp;(decode&nbsp;bits&nbsp;tree)<br>&nbsp;&nbsp;(define&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;bits&nbsp;current</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;bits)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(choose</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;(car&nbsp;bits)&nbsp;current</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(symbol</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;(cdr&nbsp;bits)&nbsp;tree))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;(cdr&nbsp;bits)&nbsp;next</span><span style="color: #000000;">-</span><span style="color: #000000;">branch)))))<br>&nbsp;&nbsp;(decode</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;bits&nbsp;tree))<br>(define&nbsp;(choose</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;bit&nbsp;branch)<br>&nbsp;&nbsp;(cond&nbsp;((</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bit&nbsp;0)&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bit&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;(right</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;(display&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">bad&nbsp;bit&nbsp;--CHOOSE-BRANCH</span><span style="color: #800000;">"</span><span style="color: #000000;">))))<br>(define&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;x&nbsp;set)<br>&nbsp;&nbsp;(cond&nbsp;((null?&nbsp;set)&nbsp;(list&nbsp;x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;(weight&nbsp;x)&nbsp;(weight&nbsp;(car&nbsp;set)))&nbsp;(cons&nbsp;x&nbsp;set))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(car&nbsp;set)&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;x&nbsp;(cdr&nbsp;set))))))<br>(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;pairs)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;pairs)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;((pair&nbsp;(car&nbsp;pairs)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf&nbsp;(car&nbsp;pair)&nbsp;(cadr&nbsp;pair))&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;(cdr&nbsp;pairs))))))<br><br>;编码<br>(define&nbsp;(encode&nbsp;message&nbsp;tree)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;message)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(append&nbsp;(encode</span><span style="color: #000000;">-</span><span style="color: #000000;">symbol&nbsp;(car&nbsp;message)&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(encode&nbsp;(cdr&nbsp;message)&nbsp;tree))))<br>(define&nbsp;(encode</span><span style="color: #000000;">-</span><span style="color: #000000;">symbol&nbsp;symbol&nbsp;tree)<br>&nbsp;&nbsp;(define&nbsp;(iter&nbsp;branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(leaf?&nbsp;branch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">()</span><span style="color: #800000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(memq&nbsp;symbol&nbsp;(symbols&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;0&nbsp;(iter&nbsp;(left</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;(iter&nbsp;(right</span><span style="color: #000000;">-</span><span style="color: #000000;">branch&nbsp;branch))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;))<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(memq&nbsp;symbol&nbsp;(symbols&nbsp;tree))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(iter&nbsp;tree)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(display&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">bad&nbsp;symbol&nbsp;--&nbsp;UNKNOWN&nbsp;SYMBOL</span><span style="color: #800000;">"</span><span style="color: #000000;">)))<br>;生成hufman树<br>(define&nbsp;(generate</span><span style="color: #000000;">-</span><span style="color: #000000;">huffman</span><span style="color: #000000;">-</span><span style="color: #000000;">tree&nbsp;pairs)<br>&nbsp;&nbsp;(successive</span><span style="color: #000000;">-</span><span style="color: #000000;">merge&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;pairs)))<br><br>(define&nbsp;(successive</span><span style="color: #000000;">-</span><span style="color: #000000;">merge&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)<br>&nbsp;&nbsp;(</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(null?&nbsp;(cdr&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(car&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(successive</span><span style="color: #000000;">-</span><span style="color: #000000;">merge&nbsp;(adjoin</span><span style="color: #000000;">-</span><span style="color: #000000;">set&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">code</span><span style="color: #000000;">-</span><span style="color: #000000;">tree&nbsp;(car&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cadr&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cddr&nbsp;leaf</span><span style="color: #000000;">-</span><span style="color: #000000;">set)))))</span></div>
<br><br><br><img src ="http://www.blogjava.net/killme2008/aggbug/131788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-07-23 08:56 <a href="http://www.blogjava.net/killme2008/archive/2007/07/23/131788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sicp 2.4节小题尝试解答</title><link>http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 20 Jul 2007 06:32:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/131469.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/131469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/131469.html</trackback:ping><description><![CDATA[<br>&nbsp;&nbsp;&nbsp; 这一节那是相当的有趣，抽象数据的多重表示：采用标志(tag）来区分和数据导向（data-directed）技术，稍微提了下消息传递。通过一张二维表格将类型、操作的分派机制介绍的很清楚，静态OO语言正是通过类型来决定消息的分派，而消息传递以列进行划分，每个类型都以过程来表征，也就是所谓的&#8220;智能数据对象&#8221;，两者各有优缺点。当类型增加频繁时，消息传递风格的分派更容易扩展，当操作增加频繁时，反而是显式的类型分派更为容易扩展，这一点如果有OO设计经验应该很容易体会。<br>看看习题：<br><br>习题2.73，将求导程序以数据导向方式进行修改:<br>a）题目已经说了，基于被求导表达式的类型进行分派，加法表达式或者乘法表达式都有标志来区分，而number?和variable?并没有标志进行区分，因此无法加入数据导向分派。<br>b)选择函数不变，将求导过程提取出来，根据表达式类型划分，然后用put过程安装：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">(define&nbsp;(deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">sum&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">&nbsp;var)<br>&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">sum&nbsp;(deriv&nbsp;(addend&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(deriv&nbsp;(augend&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var)))<br><br>(define&nbsp;(deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">prod&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">&nbsp;var)<br>&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">sum<br>&nbsp;&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">product&nbsp;(multiplier&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(deriv&nbsp;(multiplicand&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var))<br>&nbsp;&nbsp;&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">product&nbsp;(deriv&nbsp;(multiplier&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">)&nbsp;var)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(multiplicand&nbsp;</span><span style="color: #0000ff;">exp</span><span style="color: #000000;">))))<br><br>(define&nbsp;(install</span><span style="color: #000000;">-</span><span style="color: #000000;">deriv</span><span style="color: #000000;">-</span><span style="color: #0000ff;">package</span><span style="color: #000000;">)<br>&nbsp;&nbsp;(put&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">deriv&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">sum)<br>&nbsp;&nbsp;(put&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">deriv&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;deriv</span><span style="color: #000000;">-</span><span style="color: #000000;">prod)<br>&nbsp;&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">done)</span></div>
<br>c)我没做，不过和b差不了多少<br><br>习题2.75，很简单，跟着书上来：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">(define&nbsp;(make</span><span style="color: #000000;">-</span><span style="color: #000000;">from</span><span style="color: #000000;">-</span><span style="color: #000000;">mag</span><span style="color: #000000;">-</span><span style="color: #000000;">ang&nbsp;r&nbsp;a)<br>&nbsp;&nbsp;(define&nbsp;(dispatch&nbsp;op)<br>&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;((eq</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;op&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">real-part)&nbsp;(*&nbsp;r&nbsp;(cos&nbsp;a)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((eq?&nbsp;op&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000;">imag</span><span style="color: #000000;">-</span><span style="color: #000000;">part)&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;r&nbsp;(</span><span style="color: #0000ff;">sin</span><span style="color: #000000;">&nbsp;a)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((eq</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;op&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000; font-weight: bold;">magnitude)&nbsp;r)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((eq?&nbsp;op&nbsp;</span><span style="color: #000000; font-weight: bold;">'</span><span style="color: #000000;">angle)&nbsp;a)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display&nbsp;</span><span style="color: #000000; font-weight: bold;">"</span><span style="color: #000000; font-weight: bold;">Unknow&nbsp;op</span><span style="color: #000000; font-weight: bold;">"</span><span style="color: #000000;">)))<br>&nbsp;&nbsp;dispatch)</span></div>
将极角坐标系表示的复数用dispatch过程来表示，这正是消息传递风格。<br><br>习题2.76,在本文开头已经提了。<br><img src ="http://www.blogjava.net/killme2008/aggbug/131469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-07-20 14:32 <a href="http://www.blogjava.net/killme2008/archive/2007/07/20/131469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现二叉查找树</title><link>http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 02 Apr 2007 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/108018.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/108018.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/108018.html</trackback:ping><description><![CDATA[<p>二叉查找树（binary search tree)</p>
<p>1）概念：对于树中的每个节点n，其左子节点中保存的所有数值都小于n保存的数值，右子节点保存的数值都大于n保存的数值。</p>
<p>2）二叉查找树可以实现更为优越的查找性能，主要实现方式有数组和链表结构，相比较而言，链表实现更为容易，因为数组实现删除和添加功能需要移动数组元素（如填补删除空位等）</p>
<br>今天下午在打印问题搞定后用C#实现了一下，比java版本比较有趣的使用C#的delegate来代替遍历二叉树时的visit方法，这样一来可以在遍历时对节点进行你所想要的任何操作。我们知道C#的delegate是类型化的函数指针，而C++的函数指针可以模仿动态语言的闭包或者匿名函数。这里也有这样的味道。<br><br>代码如下，只实现了整数型的，节点定义：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BSTIntNode<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;right;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;value,&nbsp;BSTIntNode&nbsp;left,&nbsp;BSTIntNode&nbsp;right)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>然后定义一个Delegate，作为遍历时的访问方法：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">delegate</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Visit(BSTIntNode&nbsp;node);</span></div>
<br>然后就是二叉树的实现，删除算法只实现了复制删除法：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BSTIntTree<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;root;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Visit&nbsp;visit;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntTree()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;Search(BSTIntNode&nbsp;node,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(node&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(el&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;node.value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(el&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;node.value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;Search(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;Search(root,&nbsp;el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">广度优先遍历,利用队列实现,至上而下，至左而右</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;BreadthFirst()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue&nbsp;queue&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ListQueue();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue.Enqueue(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">queue.IsEmpty())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BSTIntNode)queue.Dequeue();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.left&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue.Enqueue(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.right&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue.Enqueue(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">深度优先遍历，递归实现线序，中序和后序<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">先序</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PreOrder(BSTIntNode&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreOrder(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreOrder(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PreOrder()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreOrder(root);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">中序</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;InOrder(BSTIntNode&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOrder(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOrder(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;InOrder()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOrder(root);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">后序</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PostOrder(BSTIntNode&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOrder(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOrder(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PostOrder()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOrder(root);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">插入节点操作</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Insert(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root,&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找节点位置</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.value&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(root&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">空树</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntNode(el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(prev.value&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;el)&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">大于节点，插入右子树</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntNode(el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntNode(el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">复制删除法的实现，归并删除法可能改变树的高度</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Delete(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;node,&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root,&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找节点位置</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">p.value</span><span style="color: #000000;">!=</span><span style="color: #000000;">el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.value&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;p.value&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(node.right&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(node.left&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;previous&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(temp.right&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找左字节数的最右子节点</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(previous&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;node)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;root)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(prev.left&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(root&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">没有找到节点：{0}</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">树为空！</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>注意，在树中我们维持了一个Visit的delegate，看看使用方法：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Main(</span><span style="color: #0000ff;">string</span><span style="color: #000000;">[]&nbsp;args)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntTree&nbsp;tree</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntTree();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;[]num</span><span style="color: #000000;">=</span><span style="color: #000000;">{</span><span style="color: #000000;">10</span><span style="color: #000000;">,</span><span style="color: #000000;">20</span><span style="color: #000000;">,</span><span style="color: #000000;">6</span><span style="color: #000000;">,</span><span style="color: #000000;">12</span><span style="color: #000000;">,</span><span style="color: #000000;">23</span><span style="color: #000000;">,</span><span style="color: #000000;">15</span><span style="color: #000000;">,</span><span style="color: #000000;">8</span><span style="color: #000000;">};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;num.Length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.Insert(num[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">添加遍历处理函数，可以有多个&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.visit&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Visit(printNode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">广度优先遍历</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.BreadthFirst();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">先序</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.PreOrder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">中序</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.InOrder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">后序</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.PostOrder();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.Delete(</span><span style="color: #000000;">8</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.Delete(</span><span style="color: #000000;">15</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">删除后广度优先遍历</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.BreadthFirst();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;printNode(BSTIntNode&nbsp;node)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">访问节点:{0}</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;node.value);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>
<p>可以看到，C#的delegate机制非常有趣，如果在java中恐怕需要用inner class来实现了。<br></p>
<p><br></p><img src ="http://www.blogjava.net/killme2008/aggbug/108018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-04-02 17:29 <a href="http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现栈和队列</title><link>http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 30 Mar 2007 01:44:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/107409.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/107409.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/107409.html</trackback:ping><description><![CDATA[有了前一篇<a href="/killme2008/archive/2007/03/29/107261.html">C#链表的实现</a>，实现栈和队列易如反掌。<br /><br />栈，利用单向链表实现：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> AbstractStack<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> Object Pop();<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Push(Object obj);<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty();<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> Object Top();<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Clear();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Stack : AbstractStack<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> SList list;<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Stack()<br />        {<br />            list </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SList();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.IsEmpty();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Push(Object obj)<br />        {<br />            list.Push(obj);<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> Pop()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.Pop();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> Top()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.getTail();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Clear()<br />        {<br />            list.Clear(); <br />        }<br />    }</span></div><br />队列的实现，通过双向链表实现，对于环形数组的实现请参考《<a href="/killme2008/archive/2007/02/20/100239.html">数组结构之栈与链表</a>》：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">interface</span><span style="color: rgb(0, 0, 0);"> Queue<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty();<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Enqueue(Object obj);<br />        Object Dequeue();<br />        Object First();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> ListQueue:Queue<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> LinkedList list;<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> ListQueue()<br />        {<br />            list </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> LinkedList();<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.IsEmpty();<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Enqueue(Object obj)<br />        {<br />            list.Push(obj);<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Object Dequeue()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.Shift();<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Object First()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.getHead();<br />        }<br />    }<br /></span></div><br /><img src ="http://www.blogjava.net/killme2008/aggbug/107409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-03-30 09:44 <a href="http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现链表</title><link>http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 29 Mar 2007 09:02:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/107261.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/107261.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/107261.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C#实现单向和双向链表。&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/107261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-03-29 17:02 <a href="http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构之堆 </title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100243.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:59:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100243.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100243.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100243.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100243.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100243.html</trackback:ping><description><![CDATA[1。概念：堆是一种特殊的二叉树，具备以下两种性质<br />1）每个节点的值都大于（或者都小于，称为最小堆）其子节点的值<br />2）树是完全平衡的，并且最后一层的树叶都在最左边<br />这样就定义了一个最大堆。<br /><br />2。堆可以用一个数组表示，有如下性质：<br />heap[i]&gt;=heap[2*i+1]  其中0&lt;=i&lt;=(n-1)/2<br />heap[i]&gt;=heap[2*i+2]  其中0&lt;=i&lt;=(n-2)/2<br /><br />3。用数组实现堆，<br />1）插入操作<br />自顶向下，伪代码：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">  heapEnqueue(el)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      将el放在堆尾<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> el不在根节点并且el</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">parent(el)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          交换el及其父节点<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />自底向上，伪代码：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000"> FloydAlgrithm(data[])<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">最后一个非叶节点的下标,i</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      调用moveDown(data,i,n</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)恢复以data[i]为根的树的堆性质<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>  <br />2)moveDown的方法实现，此方法是堆排序的关键，也是删除操作的关键。删除操作，将根节点删除，并把最末的树叶换到根节点，通过moveDown方法找到正确的位置，恢复堆性质。<br /><br />4。堆的一个实现：<br /><pre><pre>// heap.java<br />// demonstrates heaps<br />// to run this program: C&gt;java HeapApp<br />import java.io.*;<br />////////////////////////////////////////////////////////////////<br />class Node<br />   {<br />   private int iData;             // data item (key)<br />// -------------------------------------------------------------<br />   public Node(int key)           // constructor<br />      { iData = key; }<br />// -------------------------------------------------------------<br />   public int getKey()<br />      { return iData; }<br />// -------------------------------------------------------------<br />   public void setKey(int id)<br />      { iData = id; }<br />// -------------------------------------------------------------<br />   }  // end class Node<br />////////////////////////////////////////////////////////////////<br />class Heap<br />   {<br />   private Node[] heapArray;<br />   private int maxSize;           // size of array<br />   private int currentSize;       // number of nodes in array<br />// -------------------------------------------------------------<br />   public Heap(int mx)            // constructor<br />      {<br />      maxSize = mx;<br />      currentSize = 0;<br />      heapArray = new Node[maxSize];  // create array<br />      }<br />// -------------------------------------------------------------<br />   public boolean isEmpty()<br />      { return currentSize==0; }<br />// -------------------------------------------------------------<br />   public boolean insert(int key)<br />      {<br />      if(currentSize==maxSize)<br />         return false;<br />      Node newNode = new Node(key);<br />      heapArray[currentSize] = newNode;<br />      trickleUp(currentSize++);<br />      return true;<br />      }  // end insert()<br />// -------------------------------------------------------------<br />   public void trickleUp(int index)<br />      {<br />      int parent = (index-1) / 2;<br />      Node bottom = heapArray[index];<br /><br />      while( index &gt; 0 &amp;&amp;<br />             heapArray[parent].getKey() &lt; bottom.getKey() )<br />         {<br />         heapArray[index] = heapArray[parent];  // move it down<br />         index = parent;<br />         parent = (parent-1) / 2;<br />         }  // end while<br />      heapArray[index] = bottom;<br />      }  // end trickleUp()<br />// -------------------------------------------------------------<br />   public Node remove()           // delete item with max key<br />      {                           // (assumes non-empty list)<br />      Node root = heapArray[0];<br />      heapArray[0] = heapArray[--currentSize];<br />      trickleDown(0);<br />      return root;<br />      }  // end remove()<br />// -------------------------------------------------------------<br />   public void trickleDown(int index)<br />      {<br />      int largerChild;<br />      Node top = heapArray[index];       // save root<br />      while(index &lt; currentSize/2)       // while node has at<br />         {                               //    least one child,<br />         int leftChild = 2*index+1;<br />         int rightChild = leftChild+1;<br />                                         // find larger child<br />         if(rightChild &lt; currentSize &amp;&amp;  // (rightChild exists?)<br />                             heapArray[leftChild].getKey() &lt;<br />                             heapArray[rightChild].getKey())<br />            largerChild = rightChild;<br />         else<br />            largerChild = leftChild;<br />                                         // top &gt;= largerChild?<br />         if( top.getKey() &gt;= heapArray[largerChild].getKey() )<br />            break;<br />                                         // shift child up<br />         heapArray[index] = heapArray[largerChild];<br />         index = largerChild;            // go down<br />         }  // end while<br />      heapArray[index] = top;            // root to index<br />      }  // end trickleDown()<br />// -------------------------------------------------------------<br />   public boolean change(int index, int newValue)<br />      {<br />      if(index&lt;0 || index&gt;=currentSize)<br />         return false;<br />      int oldValue = heapArray[index].getKey(); // remember old<br />      heapArray[index].setKey(newValue);  // change to new<br /><br />      if(oldValue &lt; newValue)             // if raised,<br />         trickleUp(index);                // trickle it up<br />      else                                // if lowered,<br />         trickleDown(index);              // trickle it down<br />      return true;<br />      }  // end change()<br />// -------------------------------------------------------------<br />   public void displayHeap()<br />      {<br />      System.out.print("heapArray: ");    // array format<br />      for(int m=0; m&lt;currentSize; m++)<br />         if(heapArray[m] != null)<br />            System.out.print( heapArray[m].getKey() + " ");<br />         else<br />            System.out.print( "-- ");<br />      System.out.println();<br />                                          // heap format<br />      int nBlanks = 32;<br />      int itemsPerRow = 1;<br />      int column = 0;<br />      int j = 0;                          // current item<br />      String dots = "...............................";<br />      System.out.println(dots+dots);      // dotted top line<br /><br />      while(currentSize &gt; 0)              // for each heap item<br />         {<br />         if(column == 0)                  // first item in row?<br />            for(int k=0; k&lt;nBlanks; k++)  // preceding blanks<br />               System.out.print(' ');<br />                                          // display item<br />         System.out.print(heapArray[j].getKey());<br /><br />         if(++j == currentSize)           // done?<br />            break;<br /><br />         if(++column==itemsPerRow)        // end of row?<br />            {<br />            nBlanks /= 2;                 // half the blanks<br />            itemsPerRow *= 2;             // twice the items<br />            column = 0;                   // start over on<br />            System.out.println();         //    new row<br />            }<br />         else                             // next item on row<br />            for(int k=0; k&lt;nBlanks*2-2; k++)<br />               System.out.print(' ');     // interim blanks<br />         }  // end for<br />      System.out.println("/n"+dots+dots); // dotted bottom line<br />      }  // end displayHeap()<br />// -------------------------------------------------------------<br />   }  // end class Heap<br />////////////////////////////////////////////////////////////////<br />class HeapApp<br />   {<br />   public static void main(String[] args) throws IOException<br />      {<br />      int value, value2;<br />      Heap theHeap = new Heap(31);  // make a Heap; max size 31<br />      boolean success;<br /><br />      theHeap.insert(70);           // insert 10 items<br />      theHeap.insert(40);<br />      theHeap.insert(50);<br />      theHeap.insert(20);<br />      theHeap.insert(60);<br />      theHeap.insert(100);<br />      theHeap.insert(80);<br />      theHeap.insert(30);<br />      theHeap.insert(10);<br />      theHeap.insert(90);<br /><br />      while(true)                   // until [Ctrl]-[C]<br />         {<br />         System.out.print("Enter first letter of ");<br />         System.out.print("show, insert, remove, change: ");<br />         int choice = getChar();<br />         switch(choice)<br />            {<br />            case 's':                        // show<br />               theHeap.displayHeap();<br />               break;<br />            case 'i':                        // insert<br />               System.out.print("Enter value to insert: ");<br />               value = getInt();<br />               success = theHeap.insert(value);<br />               if( !success )<br />                  System.out.println("Can't insert; heap full");<br />               break;<br />            case 'r':                        // remove<br />               if( !theHeap.isEmpty() )<br />                  theHeap.remove();<br />               else<br />                  System.out.println("Can't remove; heap empty");<br />               break;<br />            case 'c':                        // change<br />               System.out.print("Enter current index of item: ");<br />               value = getInt();<br />               System.out.print("Enter new key: ");<br />               value2 = getInt();<br />               success = theHeap.change(value, value2);<br />               if( !success )<br />                  System.out.println("Invalid index");<br />               break;<br />            default:<br />               System.out.println("Invalid entry/n");<br />            }  // end switch<br />         }  // end while<br />      }  // end main()<br />//-------------------------------------------------------------<br />   public static String getString() throws IOException<br />      {<br />      InputStreamReader isr = new InputStreamReader(System.in);<br />      BufferedReader br = new BufferedReader(isr);<br />      String s = br.readLine();<br />      return s;<br />      }<br />//-------------------------------------------------------------<br />   public static char getChar() throws IOException<br />      {<br />      String s = getString();<br />      return s.charAt(0);<br />      }<br />//-------------------------------------------------------------<br />   public static int getInt() throws IOException<br />      {<br />      String s = getString();<br />      return Integer.parseInt(s);<br />      }<br />//-------------------------------------------------------------<br />  }  // end class HeapApp<br />////////////////////////////////////////////////////////////////</pre></pre><img src ="http://www.blogjava.net/killme2008/aggbug/100243.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:59 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100243.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构之AVL树 </title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100242.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:57:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100242.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100242.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100242.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100242.html</trackback:ping><description><![CDATA[树的平衡，我们已经知道DWL算法，不过DWL算法需要从整体上平衡树，但是树的平衡也可以局部的进行，由Adel'son-Vel'skii-Landis提出了一种经典方法，称为AVL树。<br /><br />1。概念：AVL树，或者说可适应树，是指树中每个节点的的平衡因子的绝对值不大于1，即只能为-1，0，1<br />平衡因子：节点的右子树的高度减去左子树的高度<br /><br />2。AVL树的插入：从新插入节点到根的路径上，修改遇到的节点的平衡因子即可，对其他部分没影响<br />1）向右子女的右子树插入一个节点，单旋转就可以<br />2）向右子女的左子树插入一个节点，双旋转，先围绕父节点，再围绕祖父节点<br /><br />3。AVL树的删除：从删除节点到根的路径上，任何不平衡因子的节点都需要修改，与插入不同，需要O(lgn)次旋转。<br /><br />4。一个java实现：<br />http://www.koders.com/java/fid3B5247D34968077A6EFD4216589026D343559FF9.aspx?s=avl%2Btree<img src ="http://www.blogjava.net/killme2008/aggbug/100242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:57 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 数据结构之递归 </title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100241.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:56:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100241.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100241.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100241.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100241.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100241.html</trackback:ping><description><![CDATA[1。递归的定义：<br />递归的定义由两部分组成：<br />1）称作定位点（anchor）或者基本情况（ground case），它们是一些基本元素，这些基本元素是集合序列中其他所有对象的基础。<br />2）给出除基本元素或者已创建对象之外的新对象的构造规则，可以再三使用这个规则不断产生新的对象。<br /><br />2。递归的实现：一般是由操作系统完成的，但是大部分的计算机系统的递归定义都是利用运行时堆栈实现的。在系统内，无论何时调用一个方法都会创建一个活动记录。一个递归调用并不仅仅是一个方法调用其自身，而是方法的一个instance调用相同方法的另一个instance，在计算机内部，这些调用是用不同的活动记录表示，并由系统区分。<br /><br />3。尾递归：<br />仅在方法的末尾实行一次递归调用，这样的递归叫尾递归。尾递归很容易被循环所替换，或者说它只是一个名字比较好听的循环，如：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_16_77_Open_Image" onclick="this.style.display='none'; Codehighlighter1_16_77_Open_Text.style.display='none'; Codehighlighter1_16_77_Closed_Image.style.display='inline'; Codehighlighter1_16_77_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_16_77_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_16_77_Closed_Text.style.display='none'; Codehighlighter1_16_77_Open_Image.style.display='inline'; Codehighlighter1_16_77_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> tail(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i)</span><span id="Codehighlighter1_16_77_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_16_77_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_27_75_Open_Image" onclick="this.style.display='none'; Codehighlighter1_27_75_Open_Text.style.display='none'; Codehighlighter1_27_75_Closed_Image.style.display='inline'; Codehighlighter1_27_75_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_27_75_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_27_75_Closed_Text.style.display='none'; Codehighlighter1_27_75_Open_Image.style.display='inline'; Codehighlighter1_27_75_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(i</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)</span><span id="Codehighlighter1_27_75_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_27_75_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    System.out.print(i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    tail(i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />  }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><br />替换为循环：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_17_66_Open_Image" onclick="this.style.display='none'; Codehighlighter1_17_66_Open_Text.style.display='none'; Codehighlighter1_17_66_Closed_Image.style.display='inline'; Codehighlighter1_17_66_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_17_66_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_17_66_Closed_Text.style.display='none'; Codehighlighter1_17_66_Open_Image.style.display='inline'; Codehighlighter1_17_66_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> tail2(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i)</span><span id="Codehighlighter1_17_66_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_17_66_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />   </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(;i</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     System.out.print(i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><br /><br />尾递归对一些没有显式循环结构的语言（如Prolog）特别重要<br /><br />4。非尾递归：<br />递归相比于迭代结构的优点就是非常清晰并易于理解，这一点可以在二叉树遍历上得到体现。3种遍历方式的递归版本与迭代版本在可读性上不可同日而语。<br />问题：逆序输出一行输入（以ruby语言为例）<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">def </span><span style="COLOR: #0000ff">reverse</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  s</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">STDIN</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">getc</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> s</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">chr</span><span style="COLOR: #000000">!=</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">/n</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">reverse</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000"> s</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">chr</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">reverse</span><span style="COLOR: #000000"> </span></div><br /><br />运行此程序，输入一行字符，将逆序输出，本质上是利用运行时堆栈完成的递归调用<br /><br />5。间接递归：<br />方法通过一连串的调用，然后间接地调用它自身，这样的递归称为间接递归。<br />6。嵌套递归<br />一般出现在函数的定义中，如果这个函数不仅用它自身定义，而且还江它自身作为一个参数，如：<br />     0            n=0<br />h(n)=n         n&gt;4<br />h(2+h(2n))   n&lt;=4<br /><br />7。过分递归：递归带来的逻辑简单性和可读性的代价是拖长了运行时间并且相对于非递归方法，它占用了更多的运行时堆栈空间。如果递归层次太深，可能导致运行时堆栈溢出，程序非正常结束的错误。<br /><br />8。回溯（backtracking技术）：在某点有多条道路供选择的时候，但不清楚哪一条能解决问题。在尝试一条道路失败后，返回岔口再试另一条道路。但是必须确定所有的道路都是可尝试的，可返回的。这种技术成为回溯。<br />在迷宫问题中和8皇后问题中使用此技术。具体程序不再列出（好长@_@）<br /><img src ="http://www.blogjava.net/killme2008/aggbug/100241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:56 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>算法之简单排序 </title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100240.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:54:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100240.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100240.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100240.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100240.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100240.html</trackback:ping><description><![CDATA[一。直接插入排序<br />1。直接插入排序：<font size="4"><span style="FONT-FAMILY: 宋体">直接插入排序是一种简单的排序方法，它的基本思想是将待排序的记录按照其值的大小插入到已排好序的有序表的适当位置，直到全部插入完为止。举个整型的排序例子<br />2。直接插入排序的伪代码：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">insertionsort(data[])<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> to data.length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />       tmp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[i];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />       将所有大于tmp的元素data[j]向后移动一位;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />       将tmp放在正确的位置上;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />3.简单例子，以整型为例。<br />A）ruby语言实现：<br />  
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">def insertion_sort(a)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  i</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    tmp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[i]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      break </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> tmp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">a[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      a[j]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      j</span><span style="COLOR: #000000">-=</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    a[j]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">tmp<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    i</span><span style="COLOR: #000000">+=</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end       <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />a</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">[</span><span style="COLOR: #800000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">3</span><span style="COLOR: #000000">]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />insertion_sort(a)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />a</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">each</span><span style="COLOR: #000000">{</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">i </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s</span><span style="COLOR: #000000">+</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">}<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />B）java语言实现：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> com.sohu.blog.denns_zane.sort;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_63_509_Open_Image" onclick="this.style.display='none'; Codehighlighter1_63_509_Open_Text.style.display='none'; Codehighlighter1_63_509_Closed_Image.style.display='inline'; Codehighlighter1_63_509_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_63_509_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_509_Closed_Text.style.display='none'; Codehighlighter1_63_509_Open_Image.style.display='inline'; Codehighlighter1_63_509_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> InsertSort</span><span id="Codehighlighter1_63_509_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_63_509_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_107_267_Open_Image" onclick="this.style.display='none'; Codehighlighter1_107_267_Open_Text.style.display='none'; Codehighlighter1_107_267_Closed_Image.style.display='inline'; Codehighlighter1_107_267_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_107_267_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_107_267_Closed_Text.style.display='none'; Codehighlighter1_107_267_Open_Image.style.display='inline'; Codehighlighter1_107_267_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> main(String args[])</span><span id="Codehighlighter1_107_267_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_107_267_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_128_141_Open_Image" onclick="this.style.display='none'; Codehighlighter1_128_141_Open_Text.style.display='none'; Codehighlighter1_128_141_Closed_Image.style.display='inline'; Codehighlighter1_128_141_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_128_141_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_128_141_Closed_Text.style.display='none'; Codehighlighter1_128_141_Open_Image.style.display='inline'; Codehighlighter1_128_141_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> []data</span><span style="COLOR: #000000">=</span><span id="Codehighlighter1_128_141_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_128_141_Open_Text"><span style="COLOR: #000000">{</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">56</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">90</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        insertsort(data);<br /><img id="Codehighlighter1_208_261_Open_Image" onclick="this.style.display='none'; Codehighlighter1_208_261_Open_Text.style.display='none'; Codehighlighter1_208_261_Closed_Image.style.display='inline'; Codehighlighter1_208_261_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_208_261_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_208_261_Closed_Text.style.display='none'; Codehighlighter1_208_261_Open_Image.style.display='inline'; Codehighlighter1_208_261_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data.length;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)</span><span id="Codehighlighter1_208_261_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_208_261_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            System.out.print(data[i]</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_314_507_Open_Image" onclick="this.style.display='none'; Codehighlighter1_314_507_Open_Text.style.display='none'; Codehighlighter1_314_507_Closed_Image.style.display='inline'; Codehighlighter1_314_507_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_314_507_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_314_507_Closed_Text.style.display='none'; Codehighlighter1_314_507_Open_Image.style.display='inline'; Codehighlighter1_314_507_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> insertsort(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> []data)</span><span id="Codehighlighter1_314_507_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_314_507_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_356_501_Open_Image" onclick="this.style.display='none'; Codehighlighter1_356_501_Open_Text.style.display='none'; Codehighlighter1_356_501_Closed_Image.style.display='inline'; Codehighlighter1_356_501_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_356_501_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_356_501_Closed_Text.style.display='none'; Codehighlighter1_356_501_Open_Image.style.display='inline'; Codehighlighter1_356_501_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,j;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data.length;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)</span><span id="Codehighlighter1_356_501_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_356_501_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> tmp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[i];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i;j</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">tmp</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />               data[j]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            data[j]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">tmp;   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />5。算法复杂度：<br />最好情况：进行n-1次比较和2(n-1)次移动，尽管他们其实都是多余的，复杂度O(n)<br />最坏情况：具体计算略，O(n*n)<br />平均情况：O(n*n)，也就是接近最坏情况，在平均情况下，数组大小翻倍，它的排序工作将是原来的4倍。<br /><br />二。选择排序<br />1。算法描述：选择算法试图先查找一个放错位置的元素并将它放到最终位置上，以此来局部化数组元素的交换。选择值最小的元素并将它和第一个位置上的元素交换。在第i步中，查找data[i],...,data[n-1]中的最小元素，并将它和data[i]进行交换。重复此过程，直到所有的元素都放入正确的位置为止。<br /><br />2。伪代码描述：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">selectionsort(data[])<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> to data.length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        从data[i],<img src="http://www.blogjava.net/images/dot.gif" />,data[n</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]中选取最小的元素<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        将它和data[i]交换<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>  <br />3。实现，以整型数组为例：<br />1)ruby语言实现：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">def selection_sort(a)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  least</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i in (</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">(a</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">2</span><span style="COLOR: #000000">))<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    least</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> a[j]</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">a[least]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        least</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">j<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      j</span><span style="COLOR: #000000">+=</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    a[least]</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">a[i]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a[i]</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">a[least] </span><span style="COLOR: #0000ff">unless</span><span style="COLOR: #000000"> least</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">i </span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">交换</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">  end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />a</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">[</span><span style="COLOR: #800000">12</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">34</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">23</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">45</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">35</span><span style="COLOR: #000000">]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />selection_sort(a)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />a</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">each</span><span style="COLOR: #000000">{</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s</span><span style="COLOR: #000000">+</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">}<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />代码很好理解，不做解释。<br /><br />2）java语言实现：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> com</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">sohu</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">blog</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">denns_zane</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">sort</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />public class SelectionSort{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    public static </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">[] selection_sort(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> [] data){<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">least</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(i</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">){<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">+</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">least</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i;j</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000">;j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (data[j]</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">data[least])<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                    least</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">j;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (least</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">i)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            swap(data</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">least</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">i);  </span><span style="COLOR: #000000">//</span><span style="COLOR: #000000">½»»»data[i]ºÍ×îÐ¡ÔªËØ<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        }    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> data;   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    public static void swap(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">[]data</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> least</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i){<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> tmp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[least];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        data[least]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[i];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        data[i]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">tmp;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    public static void main(String args[]){<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">[] t</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">{</span><span style="COLOR: #800000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">29</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">12</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">23</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">56</span><span style="COLOR: #000000">};<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        selection_sort(t);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">t){<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">System</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">out</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">(i</span><span style="COLOR: #000000">+</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        } <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />}<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />4.算法效率：<br />任何情况下，都需要进行n*(n-1)/2次比较，也就是O(n*n)的复杂度<br />最好情况：数组已经排序，不需要交换任何元素<br />最坏情况：最大元素在第一个位置而其他元素有序时，需要进行3*(n-1)次交换，即O(n)，也是很好的结果<br /><br />三。冒泡排序<br />1。算法伪代码描述：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">bubblesort(data[])<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> to data.length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data.length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> downto i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />         如果顺序错误，就交换j和j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1位置上的元素<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />2。实现：<br />1)ruby语言实现：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">def bubble_sort(data)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> i in (</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">(data</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">2</span><span style="COLOR: #000000">))<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">length</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">i<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> data[j]</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />           data[j]</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">data[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">data[j]   </span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">交换</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">        end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        j</span><span style="COLOR: #000000">-=</span><span style="COLOR: #800000">1</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />a</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">[</span><span style="COLOR: #800000">12</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">56</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">89</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">87</span><span style="COLOR: #000000">]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />bubble_sort(a)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />a</span><span style="COLOR: #000000">.</span><span style="COLOR: #0000ff">each</span><span style="COLOR: #000000">{</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">to_s</span><span style="COLOR: #000000">+</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">}<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />2）java语言实现：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> com.sohu.blog.denns_zane.sort;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_63_604_Open_Image" onclick="this.style.display='none'; Codehighlighter1_63_604_Open_Text.style.display='none'; Codehighlighter1_63_604_Closed_Image.style.display='inline'; Codehighlighter1_63_604_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_63_604_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_604_Closed_Text.style.display='none'; Codehighlighter1_63_604_Open_Image.style.display='inline'; Codehighlighter1_63_604_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> BubbleSort</span><span id="Codehighlighter1_63_604_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_63_604_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_112_283_Open_Image" onclick="this.style.display='none'; Codehighlighter1_112_283_Open_Text.style.display='none'; Codehighlighter1_112_283_Closed_Image.style.display='inline'; Codehighlighter1_112_283_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_112_283_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_112_283_Closed_Text.style.display='none'; Codehighlighter1_112_283_Open_Image.style.display='inline'; Codehighlighter1_112_283_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> bubble_sort(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> [] data)</span><span id="Codehighlighter1_112_283_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_112_283_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data.length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data.length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;j</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">i;j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />              </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(data[j]</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">data[j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">])<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                swap(data,j,j</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_339_424_Open_Image" onclick="this.style.display='none'; Codehighlighter1_339_424_Open_Text.style.display='none'; Codehighlighter1_339_424_Closed_Image.style.display='inline'; Codehighlighter1_339_424_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_339_424_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_339_424_Closed_Text.style.display='none'; Codehighlighter1_339_424_Open_Image.style.display='inline'; Codehighlighter1_339_424_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> swap(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">[]data,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> least,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i)</span><span id="Codehighlighter1_339_424_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_339_424_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> tmp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[least];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        data[least]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">data[i];<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        data[i]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">tmp;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_468_602_Open_Image" onclick="this.style.display='none'; Codehighlighter1_468_602_Open_Text.style.display='none'; Codehighlighter1_468_602_Closed_Image.style.display='inline'; Codehighlighter1_468_602_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_468_602_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_468_602_Closed_Text.style.display='none'; Codehighlighter1_468_602_Open_Image.style.display='inline'; Codehighlighter1_468_602_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> main(String args[])</span><span id="Codehighlighter1_468_602_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_468_602_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_486_501_Open_Image" onclick="this.style.display='none'; Codehighlighter1_486_501_Open_Text.style.display='none'; Codehighlighter1_486_501_Closed_Image.style.display='inline'; Codehighlighter1_486_501_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_486_501_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_486_501_Closed_Text.style.display='none'; Codehighlighter1_486_501_Open_Image.style.display='inline'; Codehighlighter1_486_501_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">[] t</span><span style="COLOR: #000000">=</span><span id="Codehighlighter1_486_501_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_486_501_Open_Text"><span style="COLOR: #000000">{</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">29</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">56</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        bubble_sort(t);<br /><img id="Codehighlighter1_548_595_Open_Image" onclick="this.style.display='none'; Codehighlighter1_548_595_Open_Text.style.display='none'; Codehighlighter1_548_595_Closed_Image.style.display='inline'; Codehighlighter1_548_595_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_548_595_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_548_595_Closed_Text.style.display='none'; Codehighlighter1_548_595_Open_Image.style.display='inline'; Codehighlighter1_548_595_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i:t)</span><span id="Codehighlighter1_548_595_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_548_595_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            System.out.print(i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />3。算法效率：<br />冒泡排序的比较次数近似是插入排序的两倍，和选择排序相同；移动次数和插入排序相同，是选择排序的n倍。可以说，插入排序比冒泡排序快两倍。<br /></span></font><img src ="http://www.blogjava.net/killme2008/aggbug/100240.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:54 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100240.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构之栈与队列 </title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100239.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:51:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100239.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100239.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100239.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100239.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100239.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一。栈1。概念：栈（stack）是一种线性数据结构，只能访问它的一端来存储或者读取数据。栈是一种后进先出的结构（LIFO)2。栈的主要操作：.clear()——清栈.isEmpty()——检查栈是否为空.push(e)——压栈.pop()——出栈.topEl()——返回栈顶元素3。栈的java实现：使用数组链表实现/** *//** *  */package com.sohu.blog.denns...&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/02/20/100239.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/100239.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:51 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100239.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构之二叉树</title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100238.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:49:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100238.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100238.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100238.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100238.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 树、二叉树和二叉查找树		1。树的概念：		递归定义：		1） 一个空结构是一个空树		2）如果t1,...,tk是分离的树，那么以t1,...,tk的根为子节点的根结构也是树		3）只有按照1，2规则产生的结构才是树		树的概念更多用于分层结构，比如数据库管理系统的分层模型。		2。二叉树（binary tree）：所有节点都有两个子节点（可以为空），并且每个子节...&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/02/20/100238.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/100238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:49 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据结构之链表</title><link>http://www.blogjava.net/killme2008/archive/2007/02/20/100237.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Feb 2007 04:44:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/02/20/100237.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/100237.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/02/20/100237.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/100237.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/100237.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 数组的两大缺点：		1。若改变数组的大小就要创建一个新的数组，并需要从原数组复制所有的数据到新的数组		2。数组元素在内存中依次顺序存储，这意味着向数组插入一项要移动数组中的其他元素		因此，我们使用链式结构，链式结构是存储数据的结点以及指向其他节点的指针的集合。如此一来，节点可以位于内存的任意位置，而且从一个节点到另一个节点的传递可以通过在结构中存储节点间引用来实现。		一。单向...&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/02/20/100237.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/100237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-02-20 12:44 <a href="http://www.blogjava.net/killme2008/archive/2007/02/20/100237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>