﻿<?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/dongwq/category/41925.html</link><description>过去理解的，现在未必理解。
过去懂得的，重温必有新意。
整理过去，整理现在。成就现在，成就未来。</description><language>zh-cn</language><lastBuildDate>Sun, 31 Jan 2010 11:06:45 GMT</lastBuildDate><pubDate>Sun, 31 Jan 2010 11:06:45 GMT</pubDate><ttl>60</ttl><item><title>AC算法使用例子</title><link>http://www.blogjava.net/dongwq/archive/2010/01/21/310445.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Thu, 21 Jan 2010 15:46:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2010/01/21/310445.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/310445.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2010/01/21/310445.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/310445.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/310445.html</trackback:ping><description><![CDATA[<p>/**<br />
&nbsp; * 实现测试：串匹配和词频统计功能<br />
&nbsp; */<br />
&nbsp;public&nbsp; void largerTextExample()<br />
&nbsp;{<br />
&nbsp;&nbsp;String text = "你好abc,ac,abc,def,ac,okt, ac,dfdfe, ac , what is it 你好啊,bc";<br />
&nbsp;&nbsp;String[] terms = {"你好","ac",&nbsp;"abc", "bc"};<br />
&nbsp;&nbsp;for (int i = 0; i &lt; terms.length; i++)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;tree.add(terms[i].getBytes(), terms[i]);<br />
&nbsp;&nbsp;&nbsp;System.out.println( terms[i]);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;tree.prepare();</p>
<p>&nbsp;&nbsp;Set termsThatHit = new HashSet();<br />
&nbsp;&nbsp;Iterator iter = tree.search(text.getBytes());<br />
&nbsp;&nbsp;<br />
//&nbsp;&nbsp;统计词频<br />
&nbsp;&nbsp;Map&lt;String, Integer&gt; freqCount = new HashMap&lt;String, Integer&gt;();<br />
&nbsp;&nbsp;for (; iter.hasNext();)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;SearchResult result = (SearchResult) iter.next();<br />
&nbsp;&nbsp;&nbsp;Set set = result.getOutputs();<br />
&nbsp;&nbsp;&nbsp;System.out.println(set);<br />
&nbsp;&nbsp;&nbsp;for(Iterator it = set.iterator();it.hasNext();)<br />
&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;String str = (String)it.next();<br />
&nbsp;&nbsp;&nbsp;&nbsp;if( freqCount.get(str) == null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;freqCount.put(str, 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;freqCount.put(str, freqCount.get(str)+1);<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;for(String key: freqCount.keySet())<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;System.out.println( "key = " + key + ", value "+ freqCount.get(key) );<br />
&nbsp;&nbsp;}<br />
<br />
------------结果-------------------------<br />
你好<br />
ac<br />
abc<br />
bc<br />
[你好]<br />
[abc, bc]<br />
[ac]<br />
[abc, bc]<br />
[ac]<br />
[ac]<br />
[ac]<br />
[你好]<br />
[bc]<br />
key = abc, value 2<br />
key = 你好, value 2<br />
key = ac, value 4<br />
key = bc, value 3</p><img src ="http://www.blogjava.net/dongwq/aggbug/310445.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2010-01-21 23:46 <a href="http://www.blogjava.net/dongwq/archive/2010/01/21/310445.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用用最小堆来找最大的K个数</title><link>http://www.blogjava.net/dongwq/archive/2009/12/06/304902.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Sun, 06 Dec 2009 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/12/06/304902.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/304902.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/12/06/304902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/304902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/304902.html</trackback:ping><description><![CDATA[<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_0_21_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_21_Open_Text.style.display='none'; Codehighlighter1_0_21_Closed_Image.style.display='inline'; Codehighlighter1_0_21_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_0_21_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_21_Closed_Text.style.display='none'; Codehighlighter1_0_21_Open_Image.style.display='inline'; Codehighlighter1_0_21_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /><span id="Codehighlighter1_0_21_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">/**&nbsp;*/</span><span id="Codehighlighter1_0_21_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;最小堆化，使用递归<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&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;minHeapity(</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;size)<br />
<img id="Codehighlighter1_74_373_Open_Image" onclick="this.style.display='none'; Codehighlighter1_74_373_Open_Text.style.display='none'; Codehighlighter1_74_373_Closed_Image.style.display='inline'; Codehighlighter1_74_373_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_74_373_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_74_373_Closed_Text.style.display='none'; Codehighlighter1_74_373_Open_Image.style.display='inline'; Codehighlighter1_74_373_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_74_373_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"  alt="" /></span><span id="Codehighlighter1_74_373_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;left&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">&lt;&lt;</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;</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;i&nbsp;*&nbsp;2&nbsp;+&nbsp;1,当下标从0正式开始时</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></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;right&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">&lt;&lt;</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;</span><span style="color: #000000">2</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;t;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(left&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;size&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;a[left]&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;a[i])<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;left;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;i;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(right&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;size&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;a[right]&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;a[t])<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;right;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(t&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;i)<br />
<img id="Codehighlighter1_300_370_Open_Image" onclick="this.style.display='none'; Codehighlighter1_300_370_Open_Text.style.display='none'; Codehighlighter1_300_370_Closed_Image.style.display='inline'; Codehighlighter1_300_370_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_300_370_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_300_370_Closed_Text.style.display='none'; Codehighlighter1_300_370_Open_Image.style.display='inline'; Codehighlighter1_300_370_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_300_370_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"  alt="" /></span><span id="Codehighlighter1_300_370_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[t]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a[i]&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;a[t]&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;(a[i]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a[t]);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;minHeapity(a,&nbsp;t,&nbsp;size);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_376_421_Open_Image" onclick="this.style.display='none'; Codehighlighter1_376_421_Open_Text.style.display='none'; Codehighlighter1_376_421_Closed_Image.style.display='inline'; Codehighlighter1_376_421_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_376_421_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_376_421_Closed_Text.style.display='none'; Codehighlighter1_376_421_Open_Image.style.display='inline'; Codehighlighter1_376_421_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_376_421_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">/**&nbsp;*/</span><span id="Codehighlighter1_376_421_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;最小堆化，不使用递归，并且合并表示<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@param</span><span style="color: #008000">&nbsp;size<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&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;minHeapityNOCur(</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;size)<br />
<img id="Codehighlighter1_479_751_Open_Image" onclick="this.style.display='none'; Codehighlighter1_479_751_Open_Text.style.display='none'; Codehighlighter1_479_751_Closed_Image.style.display='inline'; Codehighlighter1_479_751_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_479_751_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_479_751_Closed_Text.style.display='none'; Codehighlighter1_479_751_Open_Image.style.display='inline'; Codehighlighter1_479_751_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_479_751_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"  alt="" /></span><span id="Codehighlighter1_479_751_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;p&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;i;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(p&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;size)<br />
<img id="Codehighlighter1_516_748_Open_Image" onclick="this.style.display='none'; Codehighlighter1_516_748_Open_Text.style.display='none'; Codehighlighter1_516_748_Closed_Image.style.display='inline'; Codehighlighter1_516_748_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_516_748_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_516_748_Closed_Text.style.display='none'; Codehighlighter1_516_748_Open_Image.style.display='inline'; Codehighlighter1_516_748_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_516_748_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"  alt="" /></span><span id="Codehighlighter1_516_748_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&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;p&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;</span><span style="color: #000000">1</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;q指向最小的孩子结点</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;q&nbsp;</span><span style="color: #000000">&gt;=</span><span style="color: #000000">&nbsp;size)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;q&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;(size</span><span style="color: #000000">-</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;a[q</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;a[q])<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&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">;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;q&nbsp;指向右</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;a[q]&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;a[p])<br />
<img id="Codehighlighter1_663_720_Open_Image" onclick="this.style.display='none'; Codehighlighter1_663_720_Open_Text.style.display='none'; Codehighlighter1_663_720_Closed_Image.style.display='inline'; Codehighlighter1_663_720_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_663_720_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_663_720_Closed_Text.style.display='none'; Codehighlighter1_663_720_Open_Image.style.display='inline'; Codehighlighter1_663_720_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_663_720_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"  alt="" /></span><span id="Codehighlighter1_663_720_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[q]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a[p]&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;a[q]&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;(&nbsp;a[p]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a[q]);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;q;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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">break</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">已经不用调整了</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&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;maxK(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;k)<br />
<img id="Codehighlighter1_780_1523_Open_Image" onclick="this.style.display='none'; Codehighlighter1_780_1523_Open_Text.style.display='none'; Codehighlighter1_780_1523_Closed_Image.style.display='inline'; Codehighlighter1_780_1523_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_780_1523_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_780_1523_Closed_Text.style.display='none'; Codehighlighter1_780_1523_Open_Image.style.display='inline'; Codehighlighter1_780_1523_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_780_1523_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"  alt="" /></span><span id="Codehighlighter1_780_1523_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">[]&nbsp;maxKs&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">[k];<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000"><br />
<img id="Codehighlighter1_818_1456_Open_Image" onclick="this.style.display='none'; Codehighlighter1_818_1456_Open_Text.style.display='none'; Codehighlighter1_818_1456_Closed_Image.style.display='inline'; Codehighlighter1_818_1456_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_818_1456_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_818_1456_Closed_Text.style.display='none'; Codehighlighter1_818_1456_Open_Image.style.display='inline'; Codehighlighter1_818_1456_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_818_1456_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"  alt="" /></span><span id="Codehighlighter1_818_1456_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Scanner&nbsp;scan&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Scanner(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;File(</span><span style="color: #000000">"</span><span style="color: #000000">IntNums10K.txt</span><span style="color: #000000">"</span><span style="color: #000000">));<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;k;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_913_989_Open_Image" onclick="this.style.display='none'; Codehighlighter1_913_989_Open_Text.style.display='none'; Codehighlighter1_913_989_Closed_Image.style.display='inline'; Codehighlighter1_913_989_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_913_989_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_913_989_Closed_Text.style.display='none'; Codehighlighter1_913_989_Open_Image.style.display='inline'; Codehighlighter1_913_989_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_913_989_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"  alt="" /></span><span id="Codehighlighter1_913_989_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;(scan.hasNextInt())<br />
<img id="Codehighlighter1_946_984_Open_Image" onclick="this.style.display='none'; Codehighlighter1_946_984_Open_Text.style.display='none'; Codehighlighter1_946_984_Closed_Image.style.display='inline'; Codehighlighter1_946_984_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_946_984_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_946_984_Closed_Text.style.display='none'; Codehighlighter1_946_984_Open_Image.style.display='inline'; Codehighlighter1_946_984_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_946_984_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"  alt="" /></span><span id="Codehighlighter1_946_984_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxKs[i]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;scan.nextInt();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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">最初K个值</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Arrays.toString(maxKs));<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;builder&nbsp;the&nbsp;heap</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;maxKs.length;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;</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;</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">)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;minHeapity(maxKs,&nbsp;i,&nbsp;size);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&nbsp;</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">Arrays.toString(maxKs));<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(scan.hasNextInt())<br />
<img id="Codehighlighter1_1264_1394_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1264_1394_Open_Text.style.display='none'; Codehighlighter1_1264_1394_Closed_Image.style.display='inline'; Codehighlighter1_1264_1394_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1264_1394_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1264_1394_Closed_Text.style.display='none'; Codehighlighter1_1264_1394_Open_Image.style.display='inline'; Codehighlighter1_1264_1394_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1264_1394_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"  alt="" /></span><span id="Codehighlighter1_1264_1394_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;tmpN&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;scan.nextInt();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;tmpN&nbsp;</span><span style="color: #000000">&lt;=</span><span style="color: #000000">&nbsp;maxKs[</span><span style="color: #000000">0</span><span style="color: #000000">])<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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">continue</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;maxKs[</span><span style="color: #000000">0</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;tmpN;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;minHeapity(maxKs,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;size);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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">得到最大的K个</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Arrays.toString(maxKs));<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(FileNotFoundException&nbsp;e)<br />
<img id="Codehighlighter1_1492_1520_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1492_1520_Open_Text.style.display='none'; Codehighlighter1_1492_1520_Closed_Image.style.display='inline'; Codehighlighter1_1492_1520_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1492_1520_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1492_1520_Closed_Text.style.display='none'; Codehighlighter1_1492_1520_Open_Image.style.display='inline'; Codehighlighter1_1492_1520_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_1492_1520_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"  alt="" /></span><span id="Codehighlighter1_1492_1520_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div><img src ="http://www.blogjava.net/dongwq/aggbug/304902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-12-06 11:29 <a href="http://www.blogjava.net/dongwq/archive/2009/12/06/304902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz求二叉树中节点的最大距离</title><link>http://www.blogjava.net/dongwq/archive/2009/11/14/302372.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Sat, 14 Nov 2009 13:58:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/11/14/302372.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/302372.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/11/14/302372.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/302372.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/302372.html</trackback:ping><description><![CDATA[<br />
<br />
如果我们把二叉树看成一个图，父子节点之间的连线看成是双向的，我们姑且定义&#8220;距<br />
离&#8221;为两个节点之间边的个数。<br />
写一个程序求一棵二叉树中相距最远的两个节点之间的距离。<br />
如图 3-11 所示，粗箭头的边表示最长距离：<br />
图 3-11<br />
树中相距最远的两个节点 A，B<br />
<br />
写书评，赢取《编程之美——微软技术面试心得》<a href="http://www.ieee.org.cn/BCZM.asp" target="_blank">www.ieee.org.cn/BCZM.asp</a><br />
分析与解法<br />
我们先画几个不同形状的二叉树，（如图 3-12 所示），看看能否得到一些启示。<br />
图 3-12<br />
几个例子 <br />
从例子中可以看出，相距最远的两个节点，一定是两个叶子节点，或者是一个叶子节点<br />
到它的根节点。（为什么？）<br />
【解法一】<br />
根据相距最远的两个节点一定是叶子节点这个规律，我们可以进一步讨论。<br />
对于任意一个节点，以该节点为根，假设这个根有 K 个孩子节点，那么相距最远的两<br />
个节点 U 和 V 之间的路径与这个根节点的关系有两种情况：<br />
1. 若路径经过根Root，则U和V是属于不同子树的，且它们都是该子树中到根节点最远<br />
的节点，否则跟它们的距离最远相矛盾。这种情况如图3-13所示：<br />
图 3-13<br />
相距最远的节点在左右最长的子树中<br />
<br />
写书评，赢取《编程之美——微软技术面试心得》<a href="http://www.ieee.org.cn/BCZM.asp" target="_blank">www.ieee.org.cn/BCZM.asp</a><br />
2. 如果路径不经过Root，那么它们一定属于根的K个子树之一。并且它们也是该子树中<br />
相距最远的两个顶点。如图3-14中的节点A：<br />
图 3-14<br />
相距最远的节点在某个子树下<br />
因此，问题就可以转化为在子树上的解，从而能够利用动态规划来解决。<br />
设第 K 棵子树中相距最远的两个节点：Uk 和 Vk，其距离定义为 d（Uk, Vk），那么节点<br />
Uk 或 Vk 即为子树 K 到根节点 Rk 距离最长的节点。不失一般性，我们设 Uk 为子树 K 中到根<br />
节点 Rk 距离最长的节点，其到根节点的距离定义为 d（Uk, R）。取 d（Ui, R）（1&#8804;i&#8804;k）中<br />
最大的两个值 max1 和 max2，那么经过根节点 R 的最长路径为 max1+max2+2，所以树 R 中<br />
相距最远的两个点的距离为：max{d（U1, V1）, &#8230;, d（Uk, Vk），max1+max2+2}。<br />
采用深度优先搜索如图 3-15，只需要遍历所有的节点一次，时间复杂度为 O（|E|）= O<br />
（|V|-1），其中 V 为点的集合，E 为边的集合。<br />
图 3-15<br />
深度遍历示意图 <br />
示例代码如下，我们使用二叉树来实现该算法。<br />
代码清单 3-11<br />
// 数据结构定义<br />
<br />
写书评，赢取《编程之美——微软技术面试心得》<a href="http://www.ieee.org.cn/BCZM.asp" target="_blank">www.ieee.org.cn/BCZM.asp</a><br />
struct NODE<br />
{<br />
&nbsp; &nbsp; NODE* pLeft;<br />
&nbsp; &nbsp; NODE* pRight;<br />
&nbsp; &nbsp; int nMaxLeft;<br />
&nbsp; &nbsp; int nMaxRight;<br />
&nbsp; &nbsp; char chValue;<br />
};<br />
int nMaxLen = 0;<br />
// 寻找树中最长的两段距离<br />
void FindMaxLen(NODE* pRoot)<br />
{<br />
&nbsp; &nbsp; // 遍历到叶子节点，返回<br />
&nbsp; &nbsp; if(pRoot == NULL)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return;<br />
&nbsp; &nbsp; }<br />
// 如果左子树为空，那么该节点的左边最长距离为0<br />
if(pRoot -&gt; pLeft == NULL)<br />
{<br />
&nbsp; &nbsp; pRoot -&gt; nMaxLeft = 0;<br />
}<br />
// 如果右子树为空，那么该节点的右边最长距离为0<br />
if(pRoot -&gt; pRight == NULL)<br />
{<br />
&nbsp; &nbsp; pRoot -&gt; nMaxRight = 0;<br />
}<br />
// 如果左子树不为空，递归寻找左子树最长距离<br />
if(pRoot -&gt; pLeft != NULL)<br />
{<br />
&nbsp; &nbsp; FindMaxLen(pRoot -&gt; pLeft);<br />
}<br />
// 如果右子树不为空，递归寻找右子树最长距离<br />
if(pRoot -&gt; pRight != NULL)<br />
{<br />
&nbsp; &nbsp; FindMaxLen(pRoot -&gt; pRight);<br />
}<br />
// 计算左子树最长节点距离<br />
if(pRoot -&gt; pLeft != NULL)<br />
{<br />
&nbsp; &nbsp; int nTempMax = 0;<br />
&nbsp; &nbsp; if(pRoot -&gt; pLeft -&gt; nMaxLeft &gt; pRoot -&gt; pLeft -&gt; nMaxRight)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;nTempMax = pRoot -&gt; pLeft -&gt; nMaxLeft;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; else<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;nTempMax = pRoot -&gt; pLeft -&gt; nMaxRight;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; pRoot -&gt; nMaxLeft = nTempMax + 1;<br />
}<br />
// 计算右子树最长节点距离<br />
if(pRoot -&gt; pRight != NULL)<br />
//<br />
//<br />
//<br />
//<br />
//<br />
左孩子<br />
右孩子<br />
左子树中的最长距离<br />
右子树中的最长距离<br />
该节点的值<br />
<br />
写书评，赢取《编程之美——微软技术面试心得》<a href="http://www.ieee.org.cn/BCZM.asp" target="_blank">www.ieee.org.cn/BCZM.asp</a><br />
{<br />
int nTempMax = 0;<br />
if(pRoot -&gt; pRight -&gt; nMaxLeft &gt; pRoot -&gt; pRight -&gt; nMaxRight)<br />
{<br />
&nbsp; &nbsp; nTempMax = pRoot -&gt; pRight -&gt; nMaxLeft;<br />
}<br />
else<br />
{<br />
&nbsp; &nbsp; nTempMax = pRoot -&gt; pRight -&gt; nMaxRight;<br />
}<br />
pRoot -&gt; nMaxRight = nTempMax + 1;<br />
}<br />
// 更新最长距离<br />
if(pRoot -&gt; nMaxLeft + pRoot -&gt; nMaxRight &gt; nMaxLen)<br />
{<br />
&nbsp; &nbsp; nMaxLen = pRoot -&gt; nMaxLeft + pRoot -&gt; nMaxRight;<br />
}<br />
} <br />
扩展问题<br />
在代码中，我们使用了递归的办法来完成问题的求解。那么是否有非递归的算法来解决<br />
这个问题呢？<br />
总结<br />
对于递归问题的分析，笔者有一些小小的体会：<br />
1. 先弄清楚递归的顺序。在递归的实现中，往往需要假设后续的调用已经完成，在此<br />
基础之上，才实现递归的逻辑。在该题中，我们就是假设已经把后面的长度计算出<br />
来了，然后继续考虑后面的逻辑；<br />
2. 分析清楚递归体的逻辑，然后写出来。比如在上面的问题中，递归体的逻辑就是如<br />
何计算两边最长的距离；<br />
3. 考虑清楚递归退出的边界条件。也就说，哪些地方应该写return。<br />
注意到以上 3 点，在面对递归问题的时候，我们将总是有章可循。<br />
-----------------------------------------------------------------------------------<br />
<p>《编程之美》读书笔记：第3.8节&#8220;求二叉树中节点的最大距离&#8221;扩展问题 收藏 <br />
&nbsp;感谢azuryy为大家分享《编程之美》第3.8节扩展问题的答案：用非递归的算法求一颗二叉树中相距最远的两个节点之间的距离。（原博客地址：http://hi.baidu.com/azuryy/blog/item/30ad10ea192424d5d439c96d.html）</p>
<p>#include &lt;stack&gt;<br />
#include &lt;algorithm&gt;<br />
using namespace std;</p>
<p>struct Node<br />
{<br />
&nbsp;&nbsp;&nbsp; bool _visited;</p>
<p>&nbsp;&nbsp;&nbsp; Node* left;<br />
&nbsp;&nbsp;&nbsp; Node* right;<br />
&nbsp;&nbsp;&nbsp; int maxLeft;<br />
&nbsp;&nbsp;&nbsp; int maxRight;</p>
<p>&nbsp;&nbsp;&nbsp; Node()<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _visited = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxLeft = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxRight = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left = NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; right = NULL;<br />
&nbsp;&nbsp;&nbsp; }<br />
};</p>
<p>int maxLen&nbsp;&nbsp; = 0;</p>
<p>stack&lt;Node*&gt; nodeStack;</p>
<p>void findMaxLen( Node* root )<br />
{<br />
&nbsp;&nbsp;&nbsp; Node* node;</p>
<p>&nbsp;&nbsp;&nbsp; if ( root == NULL ) <br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; nodeStack.push( root );<br />
&nbsp;&nbsp;&nbsp; while( !nodeStack.empty())<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node = nodeStack.top();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( node-&gt;left == NULL &amp;&amp; node-&gt;right == NULL )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nodeStack.pop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node-&gt;_visited = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( node-&gt;left ) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !node-&gt;left-&gt;_visited )<br />
&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; nodeStack.push( node-&gt;left ) ;<br />
&nbsp;&nbsp;&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; else <br />
&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; node-&gt;maxLeft = max( node-&gt;left-&gt;maxLeft,node-&gt;left-&gt;maxRight ) + 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ( !node-&gt;left || node-&gt;left-&gt;_visited ) &amp;&amp; node-&gt;right )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !node-&gt;right-&gt;_visited )<br />
&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; nodeStack.push( node-&gt;right ) ;<br />
&nbsp;&nbsp;&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; else <br />
&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; node-&gt;maxRight = max( node-&gt;right-&gt;maxLeft,node-&gt;right-&gt;maxRight ) + 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (( !node-&gt;left || node-&gt;left-&gt;_visited ) &amp;&amp; ( !node-&gt;right || node-&gt;right-&gt;_visited ))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxLen = max( maxLen, node-&gt;maxLeft + node-&gt;maxRight );<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; node-&gt;_visited = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nodeStack.pop();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p><br />
Immediate test case 1：</p>
<p>int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; Node *tmp ;<br />
&nbsp;&nbsp;&nbsp; Node* root = new Node();</p>
<p>&nbsp;&nbsp;&nbsp; tmp = new Node();<br />
&nbsp;&nbsp;&nbsp; root-&gt;left = tmp ;</p>
<p>&nbsp;&nbsp;&nbsp; tmp = new Node();<br />
&nbsp;&nbsp;&nbsp; root-&gt;right = tmp;</p>
<p>&nbsp;&nbsp;&nbsp; tmp = new Node();<br />
&nbsp;&nbsp;&nbsp; root-&gt;right-&gt;right = tmp;</p>
<p>&nbsp;&nbsp;&nbsp; tmp = new Node();<br />
&nbsp;&nbsp;&nbsp; root-&gt;right-&gt;right-&gt;right = tmp;</p>
<p>&nbsp;&nbsp;&nbsp; tmp = new Node();<br />
&nbsp;&nbsp;&nbsp; root-&gt;right-&gt;right-&gt;right-&gt;left = tmp;<br />
&nbsp;&nbsp;&nbsp; findMaxLen( root );</p>
<p>&nbsp;&nbsp;&nbsp; cout &lt;&lt; maxLen &lt;&lt; endl;<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p>&nbsp;</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/bvbook/archive/2008/07/25/2710209.aspx</p><img src ="http://www.blogjava.net/dongwq/aggbug/302372.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-11-14 21:58 <a href="http://www.blogjava.net/dongwq/archive/2009/11/14/302372.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> zz精华游戏算法整理  </title><link>http://www.blogjava.net/dongwq/archive/2009/11/07/301541.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Sat, 07 Nov 2009 05:18:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/11/07/301541.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/301541.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/11/07/301541.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/301541.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/301541.html</trackback:ping><description><![CDATA[<table class="contentpaneopen" style="margin-top: 15px; margin-bottom: 5px">
    <tbody>
        <tr>
            <td rowspan="2">
            <form action="http://www.j2megame.org/index.php/" method="post">
                <input class="digg" type="submit" alt="评分" value="12" name="submit_vote" /><input style="display: none" type="radio" alt="vote 1 star"  CHECKED value="1" name="user_rating" /><input type="hidden" value="285" name="cid" /><input type="hidden" value="http://www.j2megame.org/index.php/content/view/285/125.html" name="url" />
            </form>
            </td>
            <td class="contentheading" width="100%">精华游戏算法整理<img style="margin: 0px 5px -2px" src="http://www.j2megame.org/images/follow.gif" border="0" included="null"  $  alt="" /> </td>
        </tr>
        <tr>
            <td><span class="small"><img alt="Author" src="http://www.j2megame.org/images/author.gif" align="top" included="null"  $ /> Author: 一滴蔚蓝色 | <img alt="Date" src="http://www.j2megame.org/images/date.gif" align="top" included="null"  $ /> Date: 2007-05-17 | <img alt="View Count" src="http://www.j2megame.org/images/view.gif" align="top" included="null"  $ /> View: 8311 | <img alt="Section &amp; Category " src="http://www.j2megame.org/images/sc.gif" align="top" included="null"  $ /> 开发技术 -&nbsp;程序设计 | <img alt="Digg" src="http://www.j2megame.org/images/vote.gif" align="top" included="null"  $ /> Digg: 12 </span></td>
        </tr>
    </tbody>
</table>
<table class="contentpaneopen">
    <tbody>
        <tr>
            <td valign="top" colspan="2">
            <p><strong>游戏算法整理 算法一：A*寻路初探</strong></p>
            <p>作者： Patrick Lester<br />
            译者：<a title="Panic" href="http://blog.vckbase.com/panic/">Panic</a> 2005年3月18日</p>
            <p>译者序：很久以前就知道了A*算法，但是从未认真读过相关的文章，也没有看过代码，只是脑子里有个模糊的概念。这次决定从头开始，研究一下这个被人推崇备至的简单方法，作为学习人工智能的开始。<br />
            这篇文章非常知名，国内应该有不少人翻译过它，我没有查找，觉得翻译本身也是对自身英文水平的锻炼。经过努力，终于完成了文档，也明白的A*算法的原理。毫无疑问，作者用形象的描述，简洁诙谐的语言由浅入深的讲述了这一神奇的算法，相信每个读过的人都会对此有所认识（如果没有，那就是偶的翻译太差了 --b）。<br />
            现在是2005年7月19日的版本，应原作者要求，对文中的某些算法细节做了修改。<br />
            原文链接：<a href="http://www.gamedev.net/reference/articles/article2003.asp">http://www.gamedev.net/reference/articles/article2003.asp</a><br />
            原作者文章链接：<a href="http://www.policyalmanac.org/games/aStarTutorial.htm">http://www.policyalmanac.org/games/aStarTutorial.htm</a><br />
            以下是翻译的正文。</p>
            <p>会者不难，A*(念作A星)算法对初学者来说的确有些难度。</p>
            <p>这篇文章并不试图对这个话题作权威的陈述。取而代之的是，它只是描述算法的原理，使你可以在进一步的阅读中理解其他相关的资料。</p>
            <p>最后，这篇文章没有程序细节。你尽可以用任意的计算机程序语言实现它。如你所愿，我在文章的末尾包含了一个指向例子程序的链接。 压缩包包括C++和Blitz Basic两个语言的版本，如果你只是想看看它的运行效果，里面还包含了可执行文件。</p>
            <p>我们正在提高自己。让我们从头开始。。。</p>
            <p>序：搜索区域</p>
            <p>假设有人想从A点移动到一墙之隔的B点，如下图，绿色的是起点A，红色是终点B，蓝色方块是中间的墙。</p>
            <p><img title="" height="256" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_1.jpg" width="362" included="null"  $ /><br />
            [图1]</p>
            <p>你首先注意到，搜索区域被我们划分成了方形网格。像这样，简化搜索区域，是寻路的第一步。这一方法把搜索区域简化成了一个二维数组。数组的每一个元素是网格的一个方块，方块被标记为可通过的和不可通过的。路径被描述为从A到B我们经过的方块的集合。一旦路径被找到，我们的人就从一个方格的中心走向另一个，直到到达目的地。</p>
            <p>这些中点被称为&#8220;节点&#8221;。当你阅读其他的寻路资料时，你将经常会看到人们讨论节点。为什么不把他们描述为方格呢？因为有可能你的路径被分割成其他不是方格的结构。他们完全可以是矩形，六角形，或者其他任意形状。节点能够被放置在形状的任意位置－可以在中心，或者沿着边界，或其他什么地方。我们使用这种系统，无论如何，因为它是最简单的。</p>
            <p>开始搜索</p>
            <p>正如我们处理上图网格的方法，一旦搜索区域被转化为容易处理的节点，下一步就是去引导一次找到最短路径的搜索。在A*寻路算法中，我们通过从点A开始，检查相邻方格的方式，向外扩展直到找到目标。</p>
            <p>我们做如下操作开始搜索：</p>
            <p><br />
            &nbsp;&nbsp; 1，从点A开始，并且把它作为待处理点存入一个&#8220;开启列表&#8221;。开启列表就像一张购物清单。尽管现在列表里只有一个元素，但以后就会多起来。你的路径可能会通过它包含的方格，也可能不会。基本上，这是一个待检查方格的列表。<br />
            &nbsp;&nbsp; 2，寻找起点周围所有可到达或者可通过的方格，跳过有墙，水，或其他无法通过地形的方格。也把他们加入开启列表。为所有这些方格保存点A作为&#8220;父方格&#8221;。当我们想描述路径的时候，父方格的资料是十分重要的。后面会解释它的具体用途。<br />
            &nbsp;&nbsp; 3，从开启列表中删除点A，把它加入到一个&#8220;关闭列表&#8221;，列表中保存所有不需要再次检查的方格。</p>
            <p>在这一点，你应该形成如图的结构。在图中，暗绿色方格是你起始方格的中心。它被用浅蓝色描边，以表示它被加入到关闭列表中了。所有的相邻格现在都在开启列表中，它们被用浅绿色描边。每个方格都有一个灰色指针反指他们的父方格，也就是开始的方格。</p>
            <p><img title="" height="150" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_2.jpg" width="151" border="0" included="null"  $ /><br />
            [图2]</p>
            <p>接着，我们选择开启列表中的临近方格，大致重复前面的过程，如下。但是，哪个方格是我们要选择的呢？是那个F值最低的。</p>
            <p>路径评分</p>
            <p>选择路径中经过哪个方格的关键是下面这个等式：</p>
            <p>F = G + H</p>
            <p>这里：<br />
            &nbsp;&nbsp;&nbsp; * G = 从起点A，沿着产生的路径，移动到网格上指定方格的移动耗费。<br />
            &nbsp;&nbsp;&nbsp; * H = 从网格上那个方格移动到终点B的预估移动耗费。这经常被称为启发式的，可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。我们没办法事先知道路径的长度，因为路上可能存在各种障碍(墙，水，等等)。虽然本文只提供了一种计算H的方法，但是你可以在网上找到很多其他的方法。</p>
            <p>我们的路径是通过反复遍历开启列表并且选择具有最低F值的方格来生成的。文章将对这个过程做更详细的描述。首先，我们更深入的看看如何计算这个方程。</p>
            <p>正如上面所说，G表示沿路径从起点到当前点的移动耗费。在这个例子里，我们令水平或者垂直移动的耗费为10，对角线方向耗费为14。我们取这些值是因为沿对角线的距离是沿水平或垂直移动耗费的的根号2（别怕），或者约1.414倍。为了简化，我们用10和14近似。比例基本正确，同时我们避免了求根运算和小数。这不是只因为我们怕麻烦或者不喜欢数学。使用这样的整数对计算机来说也更快捷。你不就就会发现，如果你不使用这些简化方法，寻路会变得很慢。</p>
            <p>既然我们在计算沿特定路径通往某个方格的G值，求值的方法就是取它父节点的G值，然后依照它相对父节点是对角线方向或者直角方向(非对角线)，分别增加14和10。例子中这个方法的需求会变得更多，因为我们从起点方格以外获取了不止一个方格。</p>
            <p>H值可以用不同的方法估算。我们这里使用的方法被称为曼哈顿方法，它计算从当前格到目的格之间水平和垂直的方格的数量总和，忽略对角线方向。然后把结果乘以10。这被成为曼哈顿方法是因为它看起来像计算城市中从一个地方到另外一个地方的街区数，在那里你不能沿对角线方向穿过街区。很重要的一点，我们忽略了一切障碍物。这是对剩余距离的一个估算，而非实际值，这也是这一方法被称为启发式的原因。想知道更多？你可以在这里找到方程和额外的注解。</p>
            <p>F的值是G和H的和。第一步搜索的结果可以在下面的图表中看到。F,G和H的评分被写在每个方格里。正如在紧挨起始格右侧的方格所表示的，F被打印在左上角，G在左下角，H则在右下角。</p>
            <p><img height="255" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_3.jpg" width="362" border="0" included="null"  $ /><br />
            [图3]</p>
            <p>现在我们来看看这些方格。写字母的方格里，G = 10。这是因为它只在水平方向偏离起始格一个格距。紧邻起始格的上方，下方和左边的方格的G值都等于10。对角线方向的G值是14。</p>
            <p>H值通过求解到红色目标格的曼哈顿距离得到，其中只在水平和垂直方向移动，并且忽略中间的墙。用这种方法，起点右侧紧邻的方格离红色方格有3格距离，H值就是30。这块方格上方的方格有4格距离(记住，只能在水平和垂直方向移动)，H值是40。你大致应该知道如何计算其他方格的H值了～。</p>
            <p>每个格子的F值，还是简单的由G和H相加得到</p>
            <p>继续搜索</p>
            <p>为了继续搜索，我们简单的从开启列表中选择F值最低的方格。然后，对选中的方格做如下处理：</p>
            <p>&nbsp;&nbsp; 4，把它从开启列表中删除，然后添加到关闭列表中。<br />
            &nbsp;&nbsp; 5，检查所有相邻格子。跳过那些已经在关闭列表中的或者不可通过的(有墙，水的地形，或者其他无法通过的地形)，把他们添加进开启列表，如果他们还不在里面的话。把选中的方格作为新的方格的父节点。<br />
            &nbsp;&nbsp; 6，如果某个相邻格已经在开启列表里了，检查现在的这条路径是否更好。换句话说，检查如果我们用新的路径到达它的话，G值是否会更低一些。如果不是，那就什么都不做。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另一方面，如果新的G值更低，那就把相邻方格的父节点改为目前选中的方格（在上面的图表中，把箭头的方向改为指向这个方格）。最后，重新计算F和G的值。如果这看起来不够清晰，你可以看下面的图示。</p>
            <p>好了，让我们看看它是怎么运作的。我们最初的9格方格中，在起点被切换到关闭列表中后，还剩8格留在开启列表中。这里面，F值最低的那个是起始格右侧紧邻的格子，它的F值是40。因此我们选择这一格作为下一个要处理的方格。在紧随的图中，它被用蓝色突出显示。</p>
            <p><img title="" height="256" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_4.jpg" width="357" border="0" included="null"  $ /><br />
            [图4]</p>
            <p>首先，我们把它从开启列表中取出，放入关闭列表(这就是他被蓝色突出显示的原因)。然后我们检查相邻的格子。哦，右侧的格子是墙，所以我们略过。左侧的格子是起始格。它在关闭列表里，所以我们也跳过它。</p>
            <p>其他4格已经在开启列表里了，于是我们检查G值来判定，如果通过这一格到达那里，路径是否更好。我们来看选中格子下面的方格。它的G值是14。如果我们从当前格移动到那里，G值就会等于20(到达当前格的G值是10，移动到上面的格子将使得G值增加10)。因为G值20大于14，所以这不是更好的路径。如果你看图，就能理解。与其通过先水平移动一格，再垂直移动一格，还不如直接沿对角线方向移动一格来得简单。</p>
            <p>当我们对已经存在于开启列表中的4个临近格重复这一过程的时候，我们发现没有一条路径可以通过使用当前格子得到改善，所以我们不做任何改变。既然我们已经检查过了所有邻近格，那么就可以移动到下一格了。</p>
            <p>于是我们检索开启列表，现在里面只有7格了，我们仍然选择其中F值最低的。有趣的是，这次，有两个格子的数值都是54。我们如何选择？这并不麻烦。从速度上考虑，选择最后添加进列表的格子会更快捷。这种导致了寻路过程中，在靠近目标的时候，优先使用新找到的格子的偏好。但这无关紧要。（对相同数值的不同对待，导致不同版本的A*算法找到等长的不同路径。）</p>
            <p>那我们就选择起始格右下方的格子，如图。</p>
            <p><img title="" height="254" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_5.jpg" width="357" border="0" included="null"  $ /><br />
            [图5]</p>
            <p>这次，当我们检查相邻格的时候，发现右侧是墙，于是略过。上面一格也被略过。我们也略过了墙下面的格子。为什么呢？因为你不能在不穿越墙角的情况下直接到达那个格子。你的确需要先往下走然后到达那一格，按部就班的走过那个拐角。(注解：穿越拐角的规则是可选的。它取决于你的节点是如何放置的。)</p>
            <p>这样一来，就剩下了其他5格。当前格下面的另外两个格子目前不在开启列表中，于是我们添加他们，并且把当前格指定为他们的父节点。其余3格，两个已经在关闭列表中（起始格，和当前格上方的格子，在表格中蓝色高亮显示),于是我们略过它们。最后一格，在当前格的左侧，将被检查通过这条路径，G值是否更低。不必担心，我们已经准备好检查开启列表中的下一格了。</p>
            <p>我们重复这个过程，直到目标格被添加进<strong>关闭</strong>列表<strong>(</strong><a href="http://blog.vckbase.com/panic/archive/2005/03/20/3778.html#Note"><strong>注解</strong></a><strong>)</strong>，就如在下面的图中所看到的。</p>
            <p><img title="" height="307" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_6.jpg" width="404" border="0" included="null"  $ /><br />
            [图6]</p>
            <p>注意，起始格下方格子的父节点已经和前面不同的。之前它的G值是28，并且指向右上方的格子。现在它的G值是20，指向它上方的格子。这在寻路过程中的某处发生，当应用新路径时，G值经过检查变得低了－于是父节点被重新指定，G和F值被重新计算。尽管这一变化在这个例子中并不重要，在很多场合，这种变化会导致寻路结果的巨大变化。</p>
            <p>那么，我们怎么确定这条路径呢？很简单，从红色的目标格开始，按箭头的方向朝父节点移动。这最终会引导你回到起始格，这就是你的路径！看起来应该像图中那样。从起始格A移动到目标格B只是简单的从每个格子（节点）的中点沿路径移动到下一个，直到你到达目标点。就这么简单。</p>
            <p><img title="" height="308" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/20090529_1_7.jpg" width="411" border="0" included="null"  $ /><br />
            [图7]</p>
            <p>A*方法总结</p>
            <p>好，现在你已经看完了整个说明，让我们把每一步的操作写在一起：</p>
            <p>&nbsp;&nbsp; 1，把起始格添加到开启列表。<br />
            &nbsp;&nbsp; 2，重复如下的工作：<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a) 寻找开启列表中F值最低的格子。我们称它为当前格。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b) 把它切换到关闭列表。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c) 对相邻的8格中的每一个？<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 如果它不可通过或者已经在关闭列表中，略过它。反之如下。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 如果它不在开启列表中，把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 如果它已经在开启列表中，用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样，就把这一格的父节点改成当前格，并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序，改变之后你可能需要重新对开启列表排序。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d) 停止，当你<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 把目标格添加进了<strong>关闭</strong>列表<strong>(</strong><a href="http://blog.vckbase.com/panic/archive/2005/03/20/3778.html#Note"><strong>注解</strong></a><strong>)，</strong>这时候路径被找到，或者<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 没有找到目标格，开启列表已经空了。这时候，路径不存在。<br />
            &nbsp;&nbsp; 3.保存路径。从目标格开始，沿着每一格的父节点移动直到回到起始格。这就是你的路径。</p>
            <p>(<a id="Note" name="Note">注解</a>:在这篇文章的较早版本中，建议的做法是当目标格（或节点）被加入到开启列表，而不是关闭列表的时候停止寻路。这么做会更迅速，而且<u>几乎</u>总是能找到最短的路径，但不是绝对的。当从倒数第二个节点到最后一个（目标节点）之间的移动耗费悬殊很大时－例如刚好有一条河穿越两个节点中间，这时候旧的做法和新的做法就会有显著不同。)<br />
            <br />
            题外话</p>
            <p>离题一下，见谅，值得一提的是，当你在网上或者相关论坛看到关于A*的不同的探讨，你有时会看到一些被当作A*算法的代码而实际上他们不是。要使用 A*，你必须包含上面讨论的所有元素－－特定的开启和关闭列表，用F,G和H作路径评价。有很多其他的寻路算法，但他们并不是A*，A*被认为是他们当中最好的。Bryan Stout在这篇文章后面的参考文档中论述了一部分，包括他们的一些优点和缺点。有时候特定的场合其他算法会更好，但你必须很明确你在作什么。好了，够多的了。回到文章。</p>
            <p>实现的注解</p>
            <p>现在你已经明白了基本原理，写你的程序的时候还得考虑一些额外的东西。下面这些材料中的一些引用了我用C++和Blitz Basic写的程序，但对其他语言写的代码同样有效。</p>
            <p>1.其他单位(避免碰撞)：如果你恰好看了我的例子代码，你会发现它完全忽略了其他单位。我的寻路者事实上可以相互穿越。取决于具体的游戏，这也许可以，也许不行。如果你打算考虑其他单位，希望他们能互相绕过，我建议你只考虑静止或那些在计算路径时临近当前单位的单位，把它们当前的位置标志为可通过的。对于临近的运动着的单位，你可以通过惩罚它们各自路径上的节点，来鼓励这些寻路者找到不同的路径(更多的描述见#2).</p>
            <p>如果你选择了把其他正在移动并且远离当前寻路单位的那些单位考虑在内，你将需要实现一种方法及时预测在何时何地碰撞可能会发生，以便恰当的避免。否则你极有可能得到一条怪异的路径，单位突然转弯试图避免和一个已经不存在的单位发生碰撞。</p>
            <p>当然，你也需要写一些碰撞检测的代码，因为无论计算的时候路径有多完美，它也会因时间而改变。当碰撞发生时，一个单位必须寻找一条新路径，或者，如果另一个单位正在移动并且不是正面碰撞，在继续沿当前路径移动之前，等待那个单位离开。</p>
            <p>这些提示大概可以让你开始了。如果你想了解更多，这里有些你可能会觉得有用的链接：</p>
            <p>&nbsp;&nbsp;&nbsp; * <a href="http://www.red3d.com/cwr/steer/">自治角色的指导行为</a>：Craig Reynold在指导能力上的工作和寻路有些不同，但是它可以和寻路整合从而形成更完整的移动和碰撞检测系统。<br />
            &nbsp;&nbsp;&nbsp; * <a href="http://ducati.doc.ntu.ac.uk/uksim/uksim%2704/Papers/Simon%20Tomlinson-%2004-20/paper04-20%20CR.pdf">电脑游戏中的长短距指导</a>：指导和寻路方面著作的一个有趣的考察。这是一个pdf文件。<br />
            &nbsp;&nbsp;&nbsp; * <a href="http://www.gamasutra.com/features/game_design/19990122/movement_01.htm">协同单位移动</a>：一个两部分系列文章的第一篇，内容是关于编队和基于分组的移动，作者是帝国时代(Age of Empires)的设计者Dave Pottinger.<br />
            &nbsp;&nbsp;&nbsp; * <a href="http://www.gamasutra.com/features/19990129/implementing_01.htm">实现协同移动</a>：Dave Pottinger文章系列的第二篇。</p>
            <p>2. 不同的地形损耗：在这个教程和我附带的程序中，地形只能是二者之－可通过的和不可通过的。但是你可能会需要一些可通过的地形，但是移动耗费更高－沼泽，小山，地牢的楼梯，等等。这些都是可通过但是比平坦的开阔地移动耗费更高的地形。类似的，道路应该比自然地形移动耗费更低。</p>
            <p>这个问题很容易解决，只要在计算任何地形的G值的时候增加地形损耗就可以了。简单的给它增加一些额外的损耗就可以了。由于A*算法已经按照寻找最低耗费的路径来设计，所以很容易处理这种情况。在我提供的这个简单的例子里，地形只有可通过和不可通过两种，A*会找到最短，最直接的路径。但是在地形耗费不同的场合，耗费最低的路径也许会包含很长的移动距离－就像沿着路绕过沼泽而不是直接穿过它。</p>
            <p>一种需额外考虑的情况是被专家称之为&#8220;influence mapping&#8221;的东西（暂译为影响映射图）。就像上面描述的不同地形耗费一样，你可以创建一格额外的分数系统，并把它应用到寻路的AI中。假设你有一张有大批寻路者的地图，他们都要通过某个山区。每次电脑生成一条通过那个关口的路径，它就会变得更拥挤。如果你愿意，你可以创建一个影响映射图对有大量屠杀事件的格子施以不利影响。这会让计算机更倾向安全些的路径，并且帮助它避免总是仅仅因为路径短(但可能更危险)而持续把队伍和寻路者送到某一特定路径。</p>
            <p>另一个可能得应用是惩罚周围移动单位路径上得节点。A*的一个底限是，当一群单位同时试图寻路到接近的地点，这通常会导致路径交叠。以为一个或者多个单位都试图走相同或者近似的路径到达目的地。对其他单位已经&#8220;认领&#8221;了的节点增加一些惩罚会有助于你在一定程度上分离路径，降低碰撞的可能性。然而，如果有必要，不要把那些节点看成不可通过的，因为你仍然希望多个单位能够一字纵队通过拥挤的出口。同时，你只能惩罚那些临近单位的路径，而不是所有路径，否则你就会得到奇怪的躲避行为例如单位躲避路径上其他已经不在那里的单位。&nbsp;还有，你应该只惩罚路径当前节点和随后的节点，而不应处理已经走过并甩在身后的节点。</p>
            <p>3. 处理未知区域：你是否玩过这样的PC游戏，电脑总是知道哪条路是正确的，即使它还没有侦察过地图？对于游戏，寻路太好会显得不真实。幸运的是，这是一格可以轻易解决的问题。</p>
            <p>答案就是为每个不同的玩家和电脑（每个玩家，而不是每个单位－－那样的话会耗费大量的内存）创建一个独立的&#8220;knownWalkability&#8221;数组，每个数组包含玩家已经探索过的区域，以及被当作可通过区域的其他区域，直到被证实。用这种方法，单位会在路的死端徘徊并且导致错误的选择直到他们在周围找到路。一旦地图被探索了，寻路就像往常那样进行。</p>
            <p>4. 平滑路径：尽管A*提供了最短，最低代价的路径，它无法自动提供看起来平滑的路径。看一下我们的例子最终形成的路径（在图7）。最初的一步是起始格的右下方，如果这一步是直接往下的话，路径不是会更平滑一些吗？</p>
            <p>有几种方法来解决这个问题。当计算路径的时候可以对改变方向的格子施加不利影响，对G值增加额外的数值。也可以换种方法，你可以在路径计算完之后沿着它跑一遍，找那些用相邻格替换会让路径看起来更平滑的地方。想知道完整的结果，查看<a href="http://www.gamasutra.com/features/20010314/pinter_01.htm">Toward More Realistic Pathfinding</a>，一篇(免费，但是需要注册)Marco Pinter发表在Gamasutra.com的文章</p>
            <p>5. 非方形搜索区域：在我们的例子里，我们使用简单的2D方形图。你可以不使用这种方式。你可以使用不规则形状的区域。想想冒险棋的游戏，和游戏中那些国家。你可以设计一个像那样的寻路关卡。为此，你可能需要建立一个国家相邻关系的表格，和从一个国家移动到另一个的G值。你也需要估算H值的方法。其他的事情就和例子中完全一样了。当你需要向开启列表中添加新元素的时候，不需使用相邻的格子，取而代之的是从表格中寻找相邻的国家。</p>
            <p>类似的，你可以为一张确定的地形图创建路径点系统，路径点一般是路上，或者地牢通道的转折点。作为游戏设计者，你可以预设这些路径点。两个路径点被认为是相邻的如果他们之间的直线上没有障碍的话。在冒险棋的例子里，你可以保存这些相邻信息在某个表格里，当需要在开启列表中添加元素的时候使用它。然后你就可以记录关联的G值（可能使用两点间的直线距离），H值（可以使用到目标点的直线距离），其他都按原先的做就可以了。</p>
            <p>Amit Patel 写了其他方法的<a href="http://theory.stanford.edu/%7Eamitp/GameProgramming/MapRepresentations.html">摘要</a>。另一个在非方形区域搜索RPG地图的例子，查看我的文章<a href="http://www.policyalmanac.org/games/twoTiered.htm">Two-Tiered A* Pathfinding</a>。(译者注：译文：&nbsp; <a id="CategoryEntryList1_EntryStoryList_Entries__ctl0_TitleUrl" href="http://blog.vckbase.com/panic/archive/2005/07/21/9906.html">A*分层寻路</a>)</p>
            <p>6. 一些速度方面的提示：当你开发你自己的A*程序，或者改写我的，你会发现寻路占据了大量的CPU时间，尤其是在大地图上有大量对象在寻路的时候。如果你阅读过网上的其他材料，你会明白，即使是开发了星际争霸或帝国时代的专家，这也无可奈何。如果你觉得寻路太过缓慢，这里有一些建议也许有效：</p>
            <p>&nbsp;&nbsp;&nbsp; * 使用更小的地图或者更少的寻路者。</p>
            <p>&nbsp;&nbsp;&nbsp; * 不要同时给多个对象寻路。取而代之的是把他们加入一个队列，把寻路过程分散在几个游戏周期中。如果你的游戏以40周期每秒的速度运行，没人能察觉。但是当大量寻路者计算自己路径的时候,他们会发觉游戏速度突然变慢。</p>
            <p>&nbsp;&nbsp;&nbsp; * 尽量使用更大的地图网格。这降低了寻路中搜索的总网格数。如果你有志气，你可以设计两个或者更多寻路系统以便使用在不同场合，取决于路径的长度。这也正是专业人士的做法，用大的区域计算长的路径，然后在接近目标的时候切换到使用小格子/区域的精细寻路。如果你对这个观点感兴趣，查阅我的文章<a href="http://www.policyalmanac.org/games/twoTiered.htm">Two-Tiered A* Pathfinding</a>。(译者注：译文 :<a id="CategoryEntryList1_EntryStoryList_Entries__ctl0_TitleUrl" href="http://blog.vckbase.com/panic/archive/2005/07/21/9906.html">A*分层寻路</a>)</p>
            <p>&nbsp;&nbsp;&nbsp; * 使用路径点系统计算长路径，或者预先计算好路径并加入到游戏中。<br />
            &nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; * 预处理你的地图，表明地图中哪些区域是不可到达的。我把这些区域称作&#8220;孤岛&#8221;。事实上，他们可以是岛屿或其他被墙壁包围等无法到达的任意区域。A*的下限是，当你告诉它要寻找通往那些区域的路径时，它会搜索整个地图，直到所有可到达的方格/节点都被通过开启列表和关闭列表的计算。这会浪费大量的CPU时间。可以通过预先确定这些区域（比如通过flood-fill或类似的方法)来避免这种情况的发生,用某些种类的数组记录这些信息，在开始寻路前检查它。<br />
            &nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; * 在一个拥挤的类似迷宫的场合，把不能连通的节点看作死端。这些区域可以在地图编辑器中预先手动指定，或者如果你有雄心壮志，开发一个自动识别这些区域的算法。给定死端的所有节点可以被赋予一个唯一的标志数字。然后你就可以在寻路过程中安全的忽略所有死端，只有当起点或者终点恰好在死端的某个节点的时候才需要考虑它们。</p>
            <p>7. 维护开启列表：这是A*寻路算法最重要的组成部分。每次你访问开启列表，你都需要寻找F值最低的方格。有几种不同的方法实现这一点。你可以把路径元素随意保存，当需要寻找F值最低的元素的时候，遍历开启列表。这很简单，但是太慢了，尤其是对长路径来说。这可以通过维护一格排好序的列表来改善，每次寻找F值最低的方格只需要选取列表的首元素。当我自己实现的时候，这种方法是我的首选。</p>
            <p>在小地图。这种方法工作的很好，但它并不是最快的解决方案。更苛求速度的A*程序员使用叫做二叉堆的方法，这也是我在代码中使用的方法。凭我的经验，这种方法在大多数场合会快2～3倍，并且在长路经上速度呈几何级数提升(10倍以上速度)。如果你想了解更多关于二叉堆的内容，查阅我的文章，<a href="http://www.policyalmanac.org/games/binaryHeaps.htm">Using Binary Heaps in A* Pathfinding</a>。(译者注：译文：<a href="http://blog.vckbase.com/panic/archive/2005/03/28/4144.html">在A*寻路中使用二叉堆</a>)</p>
            <p>另一个可能的瓶颈是你在多次寻路之间清除和保存你的数据结构的方法。我个人更倾向把所有东西都存储在数组里面。虽然节点可以以面向对象的风格被动态的产生，记录和保存，我发现创建和删除对象所增加的大量时间，以及多余的管理层次减慢的整个过程的速度。但是，如果你使用数组，你需要在调用之间清理数据。这中情形你想做的最后一件事就是在寻路调用之后花点时间把一切归零，尤其是你的地图很大的时候。</p>
            <p>我通过使用一个叫做whichList(x,y)的二维数组避免这种开销，数组的每个元素表明了节点在开启列表还是在关闭列表中。尝试寻路之后，我没有清零这个数组。取而代之的是，我在新的寻路中重置onClosedList和onOpenList的数值，每次寻路两个都+5或者类似其他数值。这种方法，算法可以安全的跳过前面寻路留下的脏数据。我还在数组中储存了诸如F,G和H的值。这样一来，我只需简单的重写任何已经存在的值而无需被清除数组的操作干扰。将数据存储在多维数组中需要更多内存，所以这里需要权衡利弊。最后，你应该使用你最得心应手的方法。</p>
            <p>8. Dijkstra的算法：尽管A*被认为是通常最好的寻路算法(看前面的&#8220;题外话&#8221;),还是有一种另外的算法有它的可取之处-Dijkstra算法。 Dijkstra算法和A*本质是相同的，只有一点不同，就是Dijkstra算法没有启发式(H值总是0)。由于没有启发式，它在各个方向上平均搜索。正如你所预料，由于Dijkstra算法在找到目标前通常会探索更大的区域，所以一般会比A*更慢一些。</p>
            <p>那么为什么要使用这种算法呢？因为有时候我们并不知道目标的位置。比如说你有一个资源采集单位，需要获取某种类型的资源若干。它可能知道几个资源区域，但是它想去最近的那个。这种情况，Dijkstra算法就比A*更适合，因为我们不知道哪个更近。用A*，我们唯一的选择是依次对每个目标许路并计算距离，然后选择最近的路径。我们寻找的目标可能会有不计其数的位置，我们只想找其中最近的，而我们并不知道它在哪里，或者不知道哪个是最近的。</p>
            <p>进一步的阅读</p>
            <p>好，现在你对一些进一步的观点有了初步认识。这时，我建议你研究我的源代码。包里面包含两个版本，一个是用C++写的，另一个用Blitz Basic。顺便说一句，两个版本都注释详尽，容易阅读，这里是链接。</p>
            <p>&nbsp;&nbsp;&nbsp; * 例子代码：<a href="http://www.blitzcoder.com/cgi-bin/showcase/showcase_showentry.pl?id=turtle177604062002002208&amp;comments=no"> A* Pathfinder (2D) Version 1.9</a> </p>
            <p>如果你既不用C++也不用Blitz Basic,在C++版本里有两个小的可执行文件。Blitz Basic可以在从<a href="http://www.blitzbasic.com/">Blitz Basic</a>网站免费下载的Blitz Basic 3D(不是Blitz Plus)演示版上运行。Ben O'Neill提供一个联机演示可以在<a href="http://www.0wns.me.uk/pathfinding/">这里</a>找到。</p>
            <p>你也该看看以下的网页。读了这篇教程后，他们应该变得容易理解多了。</p>
            <p>&nbsp;&nbsp;&nbsp; * <a href="http://www-cs-students.stanford.edu/%7Eamitp/gameprog.html#Paths">Amit的 A* 页面</a>:这是由Amit Patel制作，被广泛引用的页面，如果你没有事先读这篇文章，可能会有点难以理解。值得一看。尤其要看Amit关于这个问题的自己的<a href="http://theory.stanford.edu/%7Eamitp/GameProgramming/">看法</a>。<br />
            &nbsp;&nbsp;&nbsp; * <a href="http://www.gamasutra.com/features/19970801/pathfinding.htm">Smart Moves:智能寻路</a>：Bryan Stout发表在Gamasutra.com的这篇文章需要注册才能阅读。注册是免费的而且比起这篇文章和网站的其他资源，是非常物有所值的。Bryan用Delphi写的程序帮助我学习A*，也是我的A*代码的灵感之源。它还描述了A*的几种变化。<br />
            &nbsp;&nbsp;&nbsp; * <a href="http://www.gdconf.com/archives/2000/pottinger.doc">地形分析</a>：这是一格高阶，但是有趣的话题，Dave Pottinge撰写，Ensemble Studios的专家。这家伙参与了帝国时代和君王时代的开发。别指望看懂这里所有的东西，但是这是篇有趣的文章也许会让你产生自己的想法。它包含一些对 mip-mapping，influence mapping以及其他一些高级AI/寻路观点。对"flood filling"的讨论使我有了我自己的&#8220;死端&#8221;和&#8220;孤岛&#8221;的代码的灵感，这些包含在我Blitz版本的代码中。</p>
            <p>其他一些值得一看的网站：</p>
            <p>&nbsp;&nbsp;&nbsp; * <a href="http://www.aiguru.com/pathfinding.htm">aiGuru: Pathfinding<br />
            </a>&nbsp;&nbsp;&nbsp; * <a href="http://www.gameai.com/pathfinding.html">Game AI Resource: Pathfinding<br />
            </a>&nbsp;&nbsp;&nbsp; * <a href="http://www.gamedev.net/reference/list.asp?categoryid=18#94">GameDev.net: Pathfinding</a></p>
            <p>我同样<u>高度</u>推荐下面这几本书, 里面有很多关于寻路和其他AI话题的文章。 它们也附带了实例代码的CD。这些书我都买了。另外，如果你通过下面的链接购买了它们，我会从Amazon得到几个美分。:)</p>
            好了，这就是全部。如果你刚好写一个运用这些观点的程序，我想拜读一下。你可以这样联系我：<br />
            <img height="26" alt="" src="http://blog.vckbase.com/images/vckbase_com/panic/mail2.jpg" width="211" border="0" included="null"  $ /><br />
            现在，好运！<br />
            <br />
            译者参考文献：<br />
            &nbsp;<a id="_dbd54e7a9d345896_HomePageDays_DaysList__ctl0_DayItem_DayList__ctl0_TitleUrl" href="http://blog.vckbase.com/panic/archive/2005/03/28/4144.html">在A*寻路中使用二叉堆</a><br />
            <p><a id="CategoryEntryList1_EntryStoryList_Entries__ctl0_TitleUrl" href="http://blog.vckbase.com/panic/archive/2005/07/21/9906.html">A*分层寻</a></p>
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <hr />
            <p><strong>游戏算法整理 算法二：碰撞</strong> </p>
            <div class="cnt" id="blog_text">
            <p><br />
            1.&nbsp;&nbsp; 碰撞检测和响应<br />
            <br />
            碰撞在游戏中运用的是非常广泛的，运用理论实现的碰撞，再加上一些小技巧，可以让碰撞检测做得非常精确，效率也非常高。从而增加游戏的功能和可玩性。<br />
            <br />
            2D碰撞检测<br />
            <br />
            2D的碰撞检测已经非常稳定，可以在许多著作和论文中查询到。3D的碰撞还没有找到最好的方法，现在使用的大多数方法都是建立在2D基础上的。<br />
            <br />
            碰撞检测<br />
            <br />
            碰撞的检测不仅仅是运用在游戏中，事实上，一开始的时候是运用在模拟和机器人技术上的。这些工业上的碰撞检测要求非常高，而碰撞以后的响应也是需要符合现实生活的，是需要符合人类常规认识的。游戏中的碰撞有些许的不一样，况且，更重要的，我们制作的东西充其量是商业级别，还不需要接触到纷繁复杂的数学公式。</p>
            <div align="center">
            <p><strong><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/4f98ba38a0d6bfd2d4622529.jpg" width="1" included="null"  $ /></strong></p>
            <p>图1</p>
            </div>
            <p>最理想的碰撞，我想莫过于上图，完全按照多边形的外形和运行路径规划一个范围，在这个范围当中寻找会产生阻挡的物体，不管是什么物体，产生阻挡以后，我们运动的物体都必须在那个位置产生一个碰撞的事件。最美好的想法总是在实现上有一些困难，事实上我们可以这么做，但是效率却是非常非常低下的，游戏中，甚至于工业中无法忍受这种速度，所以我们改用其它的方法来实现。<br />
            <br />
            </p>
            <div align="center">
            <p><strong><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/90a93929634010ee98250a18.jpg" width="1" included="null"  $ /></strong></p>
            <p>图2</p>
            </div>
            <p>最简单的方法如上图，我们寻找物体的中心点，然后用这个中心点来画一个圆，如果是一个3D的物体，那么我们要画的就是一个球体。在检测物体碰撞的时候，我们只要检测两个物体的半径相加是否大于这两个物体圆心的实际距离。<strong><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/f993bf310ed5c4b85fdf0e18.jpg" width="1" included="null"  $ /></strong></p>
            <div align="center">
            <p>图3</p>
            </div>
            <p>这个算法是最简单的一种，现在还在用，但是不是用来做精确的碰撞检测，而是用来提高效率的模糊碰撞检测查询，到了这个范围以后，再进行更加精密的碰撞检测。一种比较精密的碰撞检测查询就是继续这种画圆的思路，然后把物体细分，对于物体的每个部件继续画圆，然后再继续进行碰撞检测，直到系统规定的，可以容忍的误差范围以后才触发碰撞事件，进行碰撞的一些操作。<br />
            <br />
            有没有更加简单的方法呢？2D游戏中有许多图片都是方方正正的，所以我们不必把碰撞的范围画成一个圆的，而是画成一个方的。这个正方形，或者说是一个四边形和坐标轴是对齐的，所以运用数学上的一些方法，比如距离计算等还是比较方便的。这个检测方法就叫AABBs（Axis-aligned Bounding Boxes）碰撞检测，游戏中已经运用的非常广泛了，因为其速度快，效率高，计算起来非常方便，精确度也是可以忍受的。<br />
            <br />
            做到这一步，许多游戏的需求都已经满足了。但是，总是有人希望近一步优化，而且方法也是非常陈旧的：继续对物体的各个部分进行细分，对每个部件做AABB 的矩形，那这个优化以后的系统就叫做OBB系统。虽然说这个优化以后的系统也不错，但是，许多它可以运用到的地方，别人却不爱使用它，这是后面会继续介绍的地方。<br />
            <br />
            John Carmack不知道看的哪本书，他早在DOOM中已经使用了BSP系统（二分空间分割），再加上一些小技巧，他的碰撞做得就非常好了，再加上他发明的 castray算法，DOOM已经不存在碰撞的问题，解决了这样的关键技术，我想他不再需要在什么地方分心了，只要继续研究渲染引擎就可以了。（Windows游戏编程大师技巧P392～P393介绍）（凸多边形，多边形退化，左手定律）SAT系统非常复杂，是SHT（separating hyperplane theorem，分离超平面理论）的一种特殊情况。这个理论阐述的就是两个不相关的曲面，是否能够被一个超平面所分割开来，所谓分割开来的意思就是一个曲面贴在平面的一边，而另一个曲面贴在平面的另一边。我理解的就是有点像相切的意思。SAT是SHT的特殊情况，所指的就是两个曲面都是一些多边形，而那个超平面也是一个多边形，这个超平面的多边形可以在场景中的多边形列表中找到，而超平面可能就是某个多边形的表面，很巧的就是，这个表面的法线和两个曲面的切面是相对应的。接下来的证明，我想是非常复杂的事情，希望今后能够找到源代码直接运用上去。而我们现在讲究的快速开发，我想AABB就足以满足了。<br />
            <br />
            3D碰撞检测<br />
            <br />
            3D的检测就没有什么很标准的理论了，都建立在2D的基础上，我们可以沿用AABB或者OBB，或者先用球体做粗略的检测，然后用AABB和OBB作精细的检测。BSP技术不流行，但是效率不错。微软提供了D3DIntersect函数让大家使用，方便了许多，但是和通常一样，当物体多了以后就不好用了，明显的就是速度慢许多。<br />
            <br />
            碰撞反应<br />
            <br />
            碰撞以后我们需要做一些反应，比如说产生反冲力让我们反弹出去，或者停下来，或者让阻挡我们的物体飞出去，或者穿墙，碰撞最讨厌的就是穿越，本来就不合逻辑，查阅了那么多资料以后，从来没有看到过需要穿越的碰撞，有摩擦力是另外一回事。首先看看弹性碰撞。弹性碰撞就是我们初中物理中说的动量守恒。物体在碰撞前后的动量守恒，没有任何能量损失。这样的碰撞运用于打砖块的游戏中。引入质量的话，有的物体会是有一定的质量，这些物体通常来说是需要在碰撞以后进行另外一个方向的运动的，另外一些物体是设定为质量无限大的，这些物体通常是碰撞墙壁。<br />
            <br />
            当物体碰到质量非常大的物体，默认为碰到了一个弹性物体，其速度会改变，但是能量不会受到损失。一般在代码上的做法就是在速度向量上加上一个负号。<br />
            <br />
            绝对的弹性碰撞是很少有的，大多数情况下我们运用的还是非弹性碰撞。我们现在玩的大多数游戏都用的是很接近现实的非弹性碰撞，例如Pain-Killer 中的那把吸力枪，它弹出去的子弹吸附到NPC身上时的碰撞响应就是非弹性碰撞；那把残忍的分尸刀把墙打碎的初始算法就是一个非弹性碰撞，其后使用的刚体力学就是先建立在这个算法上的。那么，是的，如果需要非弹性碰撞，我们需要介入摩擦力这个因素，而我们也无法简单使用动量守恒这个公式。<br />
            <br />
            我们可以采取比较简单的方法，假设摩擦系数&#956;非常大，那么只要物体接触，并且拥有一个加速度，就可以产生一个无穷大的摩擦力，造成物体停止的状态。<br />
            <br />
            基于别人的引擎写出一个让自己满意的碰撞是不容易的，那么如果自己建立一个碰撞系统的话，以下内容是无法缺少的：<br />
            <br />
            &#8211;&nbsp;&nbsp;&nbsp;&nbsp; 一个能够容忍的碰撞系统<br />
            <br />
            &#8211;&nbsp;&nbsp;&nbsp;&nbsp; 一个从概念上可以接受的物理系统<br />
            <br />
            &#8211;&nbsp;&nbsp;&nbsp;&nbsp; 质量<br />
            <br />
            &#8211;&nbsp;&nbsp;&nbsp;&nbsp; 速度<br />
            <br />
            &#8211;&nbsp;&nbsp;&nbsp;&nbsp; 摩擦系数<br />
            <br />
            &#8211;&nbsp;&nbsp;&nbsp;&nbsp; 地心引力</p>
            <p><font face="Tahoma" size="2">http://www.gamasutra.com/features/20000330/bobic_01.htm<br />
            http://www.gamasutra.com/features/20000330/bobic_02.htm<br />
            http://www.gamasutra.com/features/20000330/bobic_03.htm</font></p>
            <p><font face="Tahoma" size="2">这三篇是高级碰撞检测。</font></p>
            <p><font face="Tahoma" size="2">&nbsp;</font></p>
            <p><font face="Tahoma" size="2">&nbsp;</font></p>
            <hr />
            <p><strong>游戏算法整理 算法三：寻路算法新思维</strong><font face="Tahoma" size="2"> </font></p>
            </div>
            <div class="cnt" id="blog_text">
            <div class="cnt" id="blog_text">
            <div id="blog_text">
            <p>目前常用寻路算法是A*方式，原理是通过不断搜索逼近目的地的路点来获得。</p>
            <p>如果通过图像模拟搜索点，可以发现：非启发式的寻路算法实际上是一种穷举法，通过固定顺序依次搜索人物周围的路点，直到找到目的地，搜索点在图像上的表现为一个不断扩大的矩形。如下：</p>
            <p align="center"><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/47c99d2fc8bbd8281e30891f.jpg" width="1" included="null"  $ /><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/7f86ea246b2a59114d088d1f.jpg" width="1" included="null"  $ />&nbsp;&nbsp;&nbsp; </p>
            <p>很快人们发现如此穷举导致搜索速度过慢，而且不是很符合逻辑，试想：如果要从（0，0）点到达（100，0）点，如果每次向东搜索时能够走通，那么干吗还要搜索其他方向呢？所以，出现了启发式的A*寻路算法，一般通过 <strong>已经走过的路程 + 到达目的地的直线距离 </strong>代价值作为搜索时的启发条件，每个点建立一个代价值，每次搜索时就从代价低的最先搜索，如下：</p>
            <p align="center"><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/39583e6db91942eb421694ce.jpg" width="1" included="null"  $ /><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/2cbe6d06ca26fa6b0308811f.jpg" width="1" included="null"  $ />&nbsp;&nbsp;&nbsp; </p>
            <p>综上所述，以上的搜索是一种矩阵式的不断逼近终点的搜索做法。优点是比较直观，缺点在于距离越远、搜索时间越长。</p>
            <p>现在，我提出一种新的AI寻路方式——<strong>矢量寻路算法</strong>。</p>
            <p>通过观察，我们可以发现，所有的最优路线，如果是一条折线，那么、其每一个拐弯点一定发生在障碍物的突出边角，而不会在还没有碰到障碍物就拐弯的情况：如下图所示：</p>
            <p align="center"><img title="" height="196" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/23a06e22bfa8d0b44723e8ce.jpg" width="249" included="null"  $ />&nbsp;</p>
            <p>我们可以发现，所有的红色拐弯点都是在障碍物（可以认为是一个凸多边形）的顶点处，所以，我们搜索路径时，其实只需要搜索这些凸多边形顶点不就可以了吗？如果将各个顶点连接成一条通路就找到了最优路线，而不需要每个点都检索一次，这样就大大减少了搜索次数，不会因为距离的增大而增大搜索时间。</p>
            <p>这种思路我尚未将其演变为算法，姑且提出一个伪程序给各位参考：</p>
            <p>1．建立各个凸多边形顶点的通路表TAB，表示顶点A到顶点B是否可达，将可达的顶点分组保存下来。如: ( (0,0) (100,0) ),这一步骤在程序刚开始时完成，不要放在搜索过程中空耗时间。</p>
            <p>2．开始搜索A点到B点的路线</p>
            <p>3．检测A点可以直达凸多边形顶点中的哪一些，挑选出最合适的顶点X1。</p>
            <p>4．检测与X1相连（能够接通）的有哪些顶点，挑出最合适的顶点X2。</p>
            <p>5．X2是否是终点B？是的话结束，否则转步骤4（X2代入X1）</p>
            <p>如此下来，搜索只发生在凸多边形的顶点，节省了大量的搜索时间，而且找到的路线无需再修剪锯齿，保证了路线的最优性。</p>
            <p>这种方法搜索理论上可以减少大量搜索点、缺点是需要实现用一段程序得出TAB表，从本质上来说是一种空间换时间的方法，而且搜索时A*能够用的启发条件，在矢量搜索时依然可以使用。</p>
            </div>
            </div>
            </div>
            <p class="cnt">&nbsp;</p>
            <p class="cnt">&nbsp;</p>
            <hr />
            <p class="cnt"><strong>游戏算法整理 算法四：战略游戏中的战争模型算法的初步探讨</strong> </p>
            <p class="cnt"></p>
            <p class="cnt"></p>
            <p class="cnt"></p>
            <p class="cnt"></p>
            <div class="cnt" id="blog_text">　 <br />
            　　《三国志》系列游戏相信大家都有所了解，而其中的（宏观）战斗时关于双方兵力，士气，兵种克制，攻击力，增援以及随战争进行兵力减少等数值的算法是十分值得研究的。或许是由于简单的缘故，我在网上几乎没有找到相关算法的文章。下面给出这个战争的数学模型算法可以保证游戏中战争的游戏性与真实性兼顾，希望可以给有需要这方面开发的人一些启迪。<br />
            假设用x(t)和y(t)表示甲乙交战双方在t时刻的兵力，如果是开始时可视为双方士兵人数。<br />
            <br />
            　　假设每一方的战斗减员率取决于双方兵力和战斗力，用f(x,y)和g(x,y)表示，每一方的增援率是给定函数用u(t)和v(t)表示。<br />
            <br />
            　　如果双方用正规部队作战（可假设是相同兵种），先分析甲方的战斗减员率f(x,y)。可知甲方士兵公开活动，处于乙方没一个士兵的监视和杀伤范围之内，一但甲方的某个士兵被杀伤，乙方的火力立即集中在其余士兵身上，所以甲方的战斗减员率只与乙方的兵力有关可射为f与y成正比，即f=ay,a表示乙方平均每个士兵对甲方士兵的杀伤率（单位时间的杀伤数），成为乙方的战斗有效系数。类似g= -bx<br />
            这个战争模型模型方程1为<br />
            <br />
            x&#8217;(t)= -a*y(t)+u(t) x&#8217;(t)是x(t)对于t 的导数<br />
            y&#8217;(t)= -b*x(t)+v(t) y&#8217;(t)是y(t)对于t的导数<br />
            <br />
            利用给定的初始兵力，战争持续时间，和增援兵力可以求出双方兵力在战争中的变化函数。<br />
            （本文中解法略）<br />
            <br />
            如果考虑由于士气和疾病等引起的非战斗减员率（一般与本放兵力成正比，设甲乙双方分别为h,w）<br />
            <br />
            可得到改进战争模型方程2：<br />
            <br />
            x&#8217;(t)= -a*y(t)-h*x(t)+u(t)<br />
            y&#8217;(t)= -b*x(t)-w*y(t)+v(t)<br />
            <br />
            利用初始条件同样可以得到双方兵力在战争中的变化函数和战争结果。<br />
            <br />
            此外还有不同兵种作战（兵种克制）的数学模型：<br />
            模型1中的战斗有效系数a可以进一步分解为a=ry*py*(sry/sx),其中ry是乙方的攻击率（每个士兵单位的攻击次数），py是每次攻击的命中率。（sry/sx）是乙方攻击的有效面积sry与甲方活动范围sx之比。类似甲方的战斗有效系数b=rx*px*(srx/sy)，rx和px是甲方的攻击率和命中率，（srx/sy）是甲方攻击的有效面积与乙方活动范围sy之比。由于增加了兵种克制的攻击范围，所以战斗减员率不光与对方兵力有关，而且随着己放兵力增加而增加。因为在一定区域内，士兵越多被杀伤的就越多。<br />
            <br />
            方程<br />
            x&#8217;(t)= -ry*py*(sry/sx)*x(t)*y(t)-h*x(t)+u(t)<br />
            y&#8217;(t)= -rx*px*(srx/sy)*x(t)*y(t)-w*y(t)+u(t) </div>
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <hr />
            <p><strong>游戏算法整理 算法五：飞行射击游戏中的碰撞检测</strong> </p>
            <p>　　在游戏中物体的碰撞是经常发生的，怎样检测物体的碰撞是一个很关键的技术问题。在RPG游戏中，一般都将场景分为许多矩形的单元，碰撞的问题被大大的简化了，只要判断精灵所在的单元是不是有其它的东西就可以了。而在飞行射击游戏（包括象荒野大镖客这样的射击游戏）中，碰撞却是最关键的技术，如果不能很好的解决，会影响玩游戏者的兴趣。因为飞行射击游戏说白了就是碰撞的游戏——躲避敌人的子弹或飞机，同时用自己的子弹去碰撞敌人。<br />
            <br />
            　　碰撞，这很简单嘛，只要两个物体的中心点距离小于它们的半径之和就可以了。确实，而且我也看到很多人是这样做的，但是，这只适合圆形的物体——圆形的半径处处相等。如果我们要碰撞的物体是两艘威力巨大的太空飞船，它是三角形或矩形或其他的什么形状，就会出现让人尴尬的情景：两艘飞船眼看就要擦肩而过，却出人意料的发生了爆炸；或者敌人的子弹穿透了你的飞船的右弦，你却安然无恙，这不是我们希望发生的。于是，我们需要一种精确的检测方法。<br />
            <br />
            　　那么，怎样才能达到我们的要求呢？其实我们的前辈们已经总结了许多这方面的经验，如上所述的半径检测法，三维中的标准平台方程法，边界框法等等。大多数游戏程序员都喜欢用边界框法，这也是我采用的方法。边界框是在编程中加进去的不可见的边界。边界框法，顾名思义，就是用边界框来检测物体是否发生了碰撞，如果两个物体的边界框相互干扰，则发生了碰撞。用什么样的边界框要视不同情况而定，用最近似的几何形状。当然，你可以用物体的准确几何形状作边界框，但出于效率的考虑，我不赞成这样做，因为游戏中的物体一般都很复杂，用复杂的边界框将增加大量的计算，尤其是浮点计算，而这正是我们想尽量避免的。但边界框也不能与准确几何形状有太大的出入，否则就象用半径法一样出现奇怪的现象。<br />
            <br />
            　　在飞行射击游戏中，我们的飞机大多都是三角形的，我们可以用三角形作近似的边界框。现在我们假设飞机是一个正三角形（或等要三角形，我想如果谁把飞机设计成左右不对称的怪物，那他的审美观一定有问题），我的飞机是正着的、向上飞的三角形，敌人的飞机是倒着的、向下飞的三角形，且飞机不会旋转（大部分游戏中都是这样的）。我们可以这样定义飞机：中心点O(Xo,Yo),三个顶点P0(X0,Y0)、P1(X1,Y1)、P2(X2,Y2)。中心点为正三角形的中心点，即中心点到三个顶点的距离相等。接下来的问题是怎样确定两个三角形互相干扰了呢？嗯，现在我们接触到问题的实质了。如果你学过平面解析几何，我相信你可以想出许多方法解决这个问题。判断一个三角形的各个顶点是否在另一个三角形里面，看起来是个不错的方法，你可以这样做，但我却发现一个小问题：一个三角形的顶点没有在另一个三角形的里面，却可能发生了碰撞，因为另一个三角形的顶点在这个三角形的里面，所以要判断两次，这很麻烦。有没有一次判断就可以的方法？我们把三角形放到极坐标平面中，中心点为原点，水平线即X轴为零度角。我们发现三角形成了这个样子：在每个角度我们都可以找到一个距离，用以描述三角形的边。既然我们找到了边到中心点的距离，那就可以用这个距离来检测碰撞。如图一，两个三角形中心点坐标分别为（Xo,Yo）和 (Xo1,Yo1),由这两个点的坐标求出两点的距离及两点连线和X轴的夹角&#952;，再由&#952;求出中心点连线与三角形边的交点到中心点的距离，用这个距离与两中心点距离比较，从而判断两三角形是否碰撞。因为三角形左右对称，所以&#952;取-90～90度区间就可以了。哈，现在问题有趣多了，-90～90度区间正是正切函数的定义域，求出&#952;之后再找对应的边到中心点的距离就容易多了，利用几何知识，如图二，将三角形的边分为三部分,即图2中红绿蓝三部分，根据&#952;在那一部分而分别对待。用正弦定理求出边到中心点的距离，即图2中浅绿色线段的长度。但是，如果飞机每次移动都这样判断一次，效率仍然很低。我们可以结合半径法来解决，先用半径法判断是否可能发生碰撞，如果可能发生碰撞，再用上面的方法精确判断是不是真的发生了碰撞，这样基本就可以了。如果飞机旋转了怎么办呢，例如，如图三所示飞机旋转了一个角度&#945;，仔细观察图三会发现，用（&#952;-&#945;）就可以求出边到中心点的距离，这时你要注意边界情况，即（&#952;-&#945;）可能大于90度或小于-90度。啰罗嗦嗦说了这么多，不知道大家明白了没有。我编写了一个简单的例程，用于说明我的意图。在例子中假设所有飞机的大小都一样，并且没有旋转。 <br />
            <br />
            <strong><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/4ec588d47add7711a08bb7ed.jpg" width="1" included="null"  $ /></strong></p>
            <p><br />
            <strong><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/47c99d2fc8c9d8281e3089ed.jpg" width="1" included="null"  $ /></strong></p>
            <p><img title="" height="1" alt="" src="http://www.j2megame.org/images/stories/users/121/technology/20090529/67be2b38cef11934b9998fed.jpg" width="1" included="null"  $ /><br />
            </p>
            <pre class="java5"><span class="co1">/////////////////////////////////////////////////////////////////////</span>
            <span class="co1">//example.cpp</span>
            <span class="co1">//碰撞检测演示</span>
            <span class="co1">//作者 李韬</span>
            <span class="co1">/////////////////////////////////////////////////////////////////////</span>
            <span class="co1">//限于篇幅，这里只给出了碰撞检测的函数</span>
            <span class="co1">//define/////////////////////////////////////////////////////////////</span>
            #define NUM_VERTICES <span class="nu0">3</span>
            #define ang_30 <span class="nu0">-0.5236</span>
            #define ang60    <span class="nu0">1.0472</span>
            #define ang120 <span class="nu0">2.0944</span>
            <span class="co1">//deftype////////////////////////////////////////////////////////////</span>
            struct object
            <span class="br0">{</span>
            <span class="kw3">float</span> xo, yo;
            <span class="kw3">float</span> radio;
            <span class="kw3">float</span> x_vel, y_vel;
            <span class="kw3">float</span> vertices<span class="br0">[</span>NUM_VERTICES<span class="br0">]</span><span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span>;
            <span class="br0">}</span>
            &nbsp;
            <span class="co1">//faction/////////////////////////////////////////////////////////////</span>
            <span class="co1">//根据角度求距离</span>
            <span class="kw3">float</span> AngToDis<span class="br0">(</span>struct object obj, <span class="kw3">float</span> angle<span class="br0">)</span>
            <span class="br0">{</span>
            <span class="kw3">float</span> dis, R;
            R = obj.<span class="me1">radius</span>;
            <span class="kw1">if</span> <span class="br0">(</span>angle &lt;= ang_30<span class="br0">)</span>
            dis = R / <span class="br0">(</span><span class="nu0">2</span> * sin<span class="br0">(</span>-angle<span class="br0">)</span><span class="br0">)</span>;
            <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">(</span>angle &gt;= <span class="nu0">0</span><span class="br0">)</span>
            dis = R / <span class="br0">(</span><span class="nu0">2</span> * sin<span class="br0">(</span>angle + ang60<span class="br0">)</span><span class="br0">)</span>;
            <span class="kw1">else</span> dis = R / <span class="br0">(</span><span class="nu0">2</span> * sin<span class="br0">(</span>ang120 - angle<span class="br0">)</span><span class="br0">)</span>;
            <span class="kw2">return</span> dis;
            <span class="br0">}</span>
            &nbsp;
            <span class="co1">//碰撞检测</span>
            <span class="kw3">int</span> CheckHit<span class="br0">(</span>struct object obj1, struct object obj2<span class="br0">)</span>
            <span class="br0">{</span>
            <span class="kw3">float</span> deltaX, deltaY, angle, distance, bumpdis;
            deltaX = abs<span class="br0">(</span>obj1.<span class="me1">xo</span> - obj2.<span class="me1">xo</span><span class="br0">)</span>;
            deltaY = obj1.<span class="me1">yo</span> - obj2.<span class="me1">yo</span>;
            distance = sqrt<span class="br0">(</span>deltaX * deltaX + deltaY * deltaY<span class="br0">)</span>;
            <span class="kw1">if</span> <span class="br0">(</span>distance &lt;= obj.<span class="me1">radio</span><span class="br0">)</span>
            <span class="br0">{</span>
            angle = atan2<span class="br0">(</span>deltaY, deltaX<span class="br0">)</span>;
            bumpdis1 = AngToDis<span class="br0">(</span>obj1, angle<span class="br0">)</span>;
            <span class="kw2">return</span> <span class="br0">(</span>distance &lt;= <span class="nu0">2</span> * bumpdis<span class="br0">)</span>;
            <span class="br0">}</span>
            ruturn <span class="nu0">0</span>;
            <span class="br0">}</span>
            <span class="co1">//End//////////////////////////////////////////////////////////////</span></pre>
            <br />
            　　上面程序只是用于演示，并不适合放在游戏中，但你应该明白它的意思，以便写出适合你自己的碰撞检测。游戏中的情况是多种多样的，没有哪种方法能适应所有情况，你一定能根据自己的情况找到最适合自己的方法。
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <hr />
            <p><strong>游戏算法整理 算法六：关于SLG中人物可到达范围计算的想法</strong> </p>
            <p>下面的没有经过实践，因此很可能是错误的，觉得有用的初学朋友读一读吧：）<br />
            希望高人指点一二 :)<br />
            <br />
            简介：<br />
            在标准的SLG游戏中，当在一个人物处按下鼠标时，会以人物为中心，向四周生成一个菱形的可移动区范围，如下：<br />
            <br />
            &nbsp; &nbsp; 0<br />
            &nbsp; 000<br />
            00s00<br />
            &nbsp; 000<br />
            &nbsp;&nbsp; 0<br />
            <br />
            这个图形在刚开始学习PASCAL时就应该写过一个画图的程序（是否有人怀念？）。那个图形和SLG的扩展路径一样。<br />
            <br />
            一、如何生成路径：<br />
            从人物所在的位置开始，向四周的四个方向扩展，之后的点再进行扩展。即从人物所在的位置从近到远进行扩展（类似广宽优先）。<br />
            <br />
            二、扩展时会遇到的问题：<br />
            1、当扩展到一个点时，人物的移动力没有了。<br />
            2、当扩展的时候遇到了一个障碍点。<br />
            3、当扩展的时候这个结点出了地图。<br />
            4、扩展的时候遇到了一个人物正好站在这个点（与2同？）。<br />
            5、扩展的点已经被扩展过了。当扩展节点的时候，每个节点都是向四周扩展，因此会产生重复的节点。<br />
            <br />
            当遇到这些问题的时候，我们就不对这些节点处理了。在程序中使用ALLPATH[]数组记录下每一个等扩展的节点，不处理这些问题节点的意思就是不把它们加入到ALLPATH[]数组中。我们如何去扩展一个结点周围的四个结点，使用这个结点的坐标加上一个偏移量就可以了，方向如下：<br />
            <br />
            &nbsp;&nbsp; 3<br />
            &nbsp;&nbsp; 0 2<br />
            &nbsp;&nbsp; 1<br />
            <br />
            偏移量定义如下：<br />
            <font color="#009900">int offx[4] = { -1, 0, 1, 0 };<br />
            int offy[4] = { 0, 1, 0, -1 };</font><br />
            <br />
            扩展一个节点的相邻的四个节点的坐标为：<br />
            <font color="#009900">for(int i=0; i&lt;4; i )<br />
            { <br />
            &nbsp;&nbsp;&nbsp;&nbsp; temp.x = temp1.x offx[i];<br />
            &nbsp;&nbsp;&nbsp;&nbsp; temp.y = temp1.y offy[i];<br />
            }</font><br />
            <br />
            三、关于地图的结构：<br />
            1、地图的二维坐标，用于确定每个图块在地图中的位置。<br />
            2、SLG中还要引入一个变量decrease表示人物经过这个图块后他的移动力的减少值。例如，一个人物现在的移动力为CurMP=5，与之相领的图块的decrease=2；这时，如果人物移动到这里，那它的移动力变成CurMP-decrease。<br />
            3、Flag域：宽度优先中好像都有这个变量，有了它，每一个点保证只被扩展一次。防止一个点被扩展多次。（一个点只被扩展一次真的能得到正确的结果吗？）<br />
            4、一个地图上的图块是否可以通过，我们使用了一个Block代表。1---不可以通过；0---可以通过。<br />
            <br />
            这样，我们可以定义一个简单的地图结构数组了：<br />
            <font color="#009900"><br />
            #define MAP_MAX_WIDTH 50<br />
            #define MAP_MAX_HEIGHT 50<br />
            typedef struct tagTILE{ <br />
            &nbsp;&nbsp;&nbsp;&nbsp; int x,y,decrease,flag,block;<br />
            }TILE,*LPTILE;<br />
            TILE pMap[MAP_MAX_WIDTH][MAP_MAX_HEIGHT];</font><br />
            <br />
            以上是顺序数组，是否使用动态的分配更好些？毕竟不能事先知道一个地图的宽、高。<br />
            <br />
            四、关于路径：<br />
            SLG游戏中的扩展路径是一片区域（以人物为中心向四周扩展，当然，当人物移动时路径只有一个）。这些扩展的路径必须要存储起来，所有要有一个好的结构。我定义了一个结构，不是很好：<br />
            <br />
            <font color="#009900">typedef struct tagNODE{ <br />
            &nbsp;&nbsp;&nbsp;&nbsp; int x,y;&nbsp;&nbsp; //扩展路径中的一个点在地图中的坐标。<br />
            &nbsp;&nbsp;&nbsp;&nbsp; int curmp; //人物到了这个点以后的当前的移动力。<br />
            }NODE,*LPNODE;<br />
            </font><br />
            上面的结构是定义扩展路径中的一个点的结构。扩展路径是点的集合，因此用如下的数组进行定义：<br />
            <br />
            <font color="#009900">NODE AllPath[PATH_MAX_LENGTH];</font><br />
            <br />
            其中的PATH_MAX_LENGTH代表扩展路径的点的个数，我们不知道这个扩展的路径中包含多少个点，因此定义一个大一点的数字使这个数组不会产生溢出：<br />
            <font color="#009900"><br />
            #define PATH_MAX_LENGTH 200</font><br />
            <br />
            上面的这个数组很有用处，以后的扩展就靠它来实现，它应该带有两个变量nodecount 代表当前的数组中有多少个点。当然，数组中的点分成两大部分，一部分是已经扩展的结点，存放在数组的前面；另一部分是等扩展的节点，放在数组的后面为什么会出现已扩展节点和待扩展节点？如下例子：<br />
            <br />
            当前的人物坐标为x,y；移动力为mp。将它存放到AllPath数组中，这时的起始节点为等扩展的节点。这时我们扩展它的四个方向，对于合法的节点（如没有出地图，也没有障碍......），我们将它们存放入AllPath数组中，这时的新加入的节点（起始节点的子节点）就是等扩展结点，而起始节点就成了已扩展节点了。下一次再扩展节点的时候，我们不能再扩展起始节点，因为它是已经扩展的节点了。我们只扩展那几个新加入的节点（待扩展节点），之后的情况以此类推。那么我们如何知道哪些是已经扩展的结点，哪些是等扩展的节点？我们使用另一个变量cutflag，在这个变量所代表的下标以前的结点是已扩展节点，在它及它之后是待扩展结点。<br />
            <br />
            五、下面是基本框架（只扩展一个人物的可达范围）：<br />
            <br />
            </p>
            <pre class="java5"><span class="kw3">int</span> nodecount = <span class="nu0">0</span>; <span class="co1">//AllPath数组中的点的个数（包含待扩展节点和已经扩展的节点</span>
            <span class="kw3">int</span> cutflag = <span class="nu0">0</span>; <span class="co1">//用于划分已经扩展的节点和待扩展节点</span>
            NODE temp; <span class="co1">//路径中的一个点（临时）</span>
            temp.<span class="me1">x</span> = pRole<span class="br0">[</span>cur<span class="br0">]</span> - &gt;x; <span class="co1">//假设有一个关于人物的类，代表当前的人物</span>
            temp.<span class="me1">y</span> = pRole<span class="br0">[</span>cur<span class="br0">]</span> - &gt;y;
            temp.<span class="me1">curmp</span> = pRole<span class="br0">[</span>cur<span class="br0">]</span> - &gt;MP; <span class="co1">//人物的最大MP</span>
            AllPath<span class="br0">[</span>nodecount<span class="br0">]</span> = temp; <span class="co1">//起始点入AllPath，此时的起始点为等扩展的节点</span>
            &nbsp;
            <span class="kw1">while</span> <span class="br0">(</span>curflag &lt; nodecount<span class="br0">)</span> <span class="br0">{</span> <span class="co1">//数组中还有待扩展的节点</span>
            <span class="kw3">int</span> n = nodecount; <span class="co1">//记录下当前的数组节点的个数。</span>
            <span class="kw1">for</span> <span class="br0">(</span><span class="kw3">int</span> i = cutflag; i &lt; nodecount; i<span class="br0">)</span> <span class="br0">{</span> <span class="co1">//遍历待扩展节点</span>
            <span class="kw1">for</span> <span class="br0">(</span><span class="kw3">int</span> j = <span class="nu0">0</span>; j &lt; <span class="nu0">4</span>; j<span class="br0">)</span> <span class="br0">{</span> <span class="co1">//向待扩展节点的四周各走一步</span>
            <span class="co1">//取得相邻点的数据</span>
            temp.<span class="me1">x</span> = AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">x</span> offx<span class="br0">[</span>j<span class="br0">]</span>;
            temp.<span class="me1">y</span> = AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">y</span> offy<span class="br0">[</span>j<span class="br0">]</span>;
            temp.<span class="me1">curmp</span> = AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">curmp</span> -
            pMap<span class="br0">[</span>AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">x</span><span class="br0">]</span><span class="br0">[</span>AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">y</span><span class="br0">]</span>.<span class="me1">decrease</span>;
            <span class="co1">//以下为检测是否为问题点的过程，如果是问题点，不加入AllPath数组，继续处理其它的点</span>
            <span class="kw1">if</span> <span class="br0">(</span>pMap<span class="br0">[</span>temp.<span class="me1">x</span><span class="br0">]</span><span class="br0">[</span>temp.<span class="me1">y</span><span class="br0">]</span>.<span class="me1">block</span><span class="br0">)</span> <span class="br0">{</span>
            <span class="kw2">continue</span>; <span class="co1">//有障碍，处理下一个节点</span>
            <span class="br0">}</span>
            <span class="kw1">if</span> <span class="br0">(</span>temp.<span class="me1">curmp</span> &lt; <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span>
            <span class="kw2">continue</span>; <span class="co1">//没有移动力了</span>
            <span class="br0">}</span>
            <span class="kw1">if</span> <span class="br0">(</span>temp.<span class="me1">x</span> &lt; <span class="nu0">0</span> || temp.<span class="me1">x</span> &gt;= MAP_MAX_WIDTH || temp.<span class="me1">y</span> &lt; <span class="nu0">0</span> ||
            temp.<span class="me1">y</span> &gt;= MAP_MAX_HEIGHT<span class="br0">)</span> <span class="br0">{</span>
            <span class="kw2">continue</span>; <span class="co1">//出了地图的范围</span>
            <span class="br0">}</span>
            <span class="kw1">if</span> <span class="br0">(</span>pMap<span class="br0">[</span>temp.<span class="me1">x</span><span class="br0">]</span><span class="br0">[</span>temp.<span class="me1">y</span><span class="br0">]</span>.<span class="me1">flag</span><span class="br0">)</span> <span class="br0">{</span>
            <span class="kw2">continue</span>; <span class="co1">//已经扩展了的结点</span>
            <span class="br0">}</span>
            <span class="co1">//经过了上面几层的检测，没有问题的节点过滤出来，可以加入AllPath</span>
            AllPath<span class="br0">[</span>nodecount<span class="br0">]</span> = temp;
            <span class="br0">}</span>
            pMap<span class="br0">[</span>AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">x</span><span class="br0">]</span><span class="br0">[</span>AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">y</span><span class="br0">]</span>.<span class="me1">flag</span> = <span class="nu0">1</span>; <span class="co1">//将已经扩展的节点标记为已扩展节点</span>
            <span class="br0">}</span>
            cutflag = n; <span class="co1">//将已扩展节点和待扩展节点的分界线下标值移动到新的分界线</span>
            <span class="br0">}</span>
            <span class="kw1">for</span> <span class="br0">(</span><span class="kw3">int</span> i = <span class="nu0">0</span>; i &lt; nodecount; i<span class="br0">)</span> <span class="br0">{</span>
            pMap<span class="br0">[</span>AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">x</span><span class="br0">]</span><span class="br0">[</span>AllPath<span class="br0">[</span>i<span class="br0">]</span>.<span class="me1">y</span><span class="br0">]</span>.<span class="me1">bFlag</span> = <span class="nu0">0</span>; <span class="co1">//标记为已扩展节点的标记设回为待扩展节点。</span>
            <span class="br0">}</span></pre>
            <p>&nbsp;</p>
            <p>&nbsp;</p>
            <hr />
            <p><strong>游戏算法整理 算法七 无限大地图的实现</strong> </p>
            <p>这已经不是什么新鲜的东西了，不过现在实在想不到什么好写，而且版面上又异常冷清，我再不说几句就想要倒闭了一样。只好暂且拿这个东西来凑数吧。 <br />
            无限大的地图，听上去非常吸引人。本来人生活的空间就是十分广阔的，人在这么广阔的空间里活动才有一种自由的感觉。游戏中的虚拟世界由于受到计算机存储空间的限制，要真实地反映这个无限的空间是不可能的。而对这个限制最大的，就是内存的容量了。所以在游戏的空间里，我们一般只能在一个狭小的范围里活动，在一般的RPG中，从一个场景走到另一个场景，即使两个地方是紧紧相连的，也要有一个场景的切换过程，一般的表现就是画面的淡入淡出。<br />
            <br />
            这样的场景切换给人一种不连续的感觉（我不知道可不可以把这种称作&#8220;蒙太奇&#8221;:o)），从城内走到城外还有情可缘，因为有道城墙嘛，但是两个地方明明没有界限，却偏偏在这一边看不到另外一边，就有点不现实了。当然这并不是毛病，一直以来的RPG都是遵循这个原则，我们（至少是我）已经习惯了这种走路的方式。我在这里说的仅仅是另外一种看起来更自然一点的走路方式，仅此而已。<br />
            <br />
            当然要把整个城市的地图一下子装进内存，现在的确是不现实的，每一次只能放一部分，那么应该怎么放才是我们要讨论的问题。<br />
            <br />
            我们在以前提到Tile方法构造地图时就谈到过Tile的好处之一就是节省内存，这里仍然可以借鉴Tile的思想。我们把整个大地图分成几块，把每一块称作一个区域，在同一时间里，内存中只保存相邻的四块区域。这里每个区域的划分都有一定的要求：每个区域大小应该相等这是一定的了，不然判断当前屏幕在哪个区域中就成了一个非常令人挠头的事；另外每个区域的大小都要大于屏幕的大小，也只有这样才能保证屏幕（就是图中那块半透明的蓝色矩形）在地图上荡来荡去的时候，最多同时只能覆盖四个区域（象左图中所表示的），内存里也只要保存四个区域就足够了；还有一点要注意的，就是地图上的建筑物（也包括树啦，大石头啦什么的）必须在一个区域内，这样也是为了画起来方便，当然墙壁——就是那种连续的围墙可以除外，因为墙壁本来就是一段一段拼起来的。 <br />
            <br />
            我们在程序中可以设定4个指针来分别指向这4个区域，当每次主角移动时，就判断当前滚动的屏幕是否移出了这四个区域，如果移出了这四个区域，那么就废弃两个（或三个）已经在目前的四个相邻区域中被滚出去的区域（说得很别扭，各位见谅），读入两个（或三个）新滚进来的区域，并重新组织指针。这里并不涉及内存区域的拷贝。<br />
            <br />
            这样的区域划分方法刚好适合我们以前提到的Tile排列方法，只要每个区域横向Tile的个数是个偶数就行了，这样相邻的两个区域拼接起来刚好严丝合缝，而且每个区域块的结构完全一致，没有那些需要重复保存的Tile（这个我想我不需要再画图说明了，大家自己随便画个草图就看得出来了）。在文件中的保存方法就是按一个个区域分别保存，这样在读取区域数据时就可以直接作为一整块读入，也简化了程序。另外还有个细节就是，我们的整个地图可能不是一个规则的矩形，可能有些地方是无法达到的，如右图所示，背景是黑色的部分代表人物不能达到的地方。那么在整个地图中，这一部分区域（在图中蓝色的3号区域）就可以省略，表现在文件存储上就是实际上不存储这一部分区域，这样可以节省下不少存储空间。对于这种地图可以用一个稀疏矩阵来存储，大家也可以发挥自己的才智用其他对于编程来说更方便的形式来存储地图。&nbsp;&nbsp;<br />
            <br />
            这就是对无限大地图实现的一种方法，欢迎大家提出更好的方法。也希望整个版面能够活跃一点。</p>
            </td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/dongwq/aggbug/301541.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-11-07 13:18 <a href="http://www.blogjava.net/dongwq/archive/2009/11/07/301541.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pku3233　矩阵相乘的反复平方法和矩阵等比和计算构造方法</title><link>http://www.blogjava.net/dongwq/archive/2009/11/02/300791.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 02 Nov 2009 13:26:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/11/02/300791.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300791.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/11/02/300791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300791.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300791.html</trackback:ping><description><![CDATA[pku3233：Given a <em>n</em> &#215; <em>n</em> matrix <em>A</em> and a positive integer <em>k</em>, find the sum <em>S</em> = <em>A</em> + <em>A</em><sup>2</sup> + <em>A</em><sup>3</sup> + &#8230; + <em>A<sup>k</sup></em>.<br />
<br />
分析：矩阵相乘O(n^3), 有k次，则复杂度为n^3*k。<br />
<br />
使用矩阵技巧，构造：<br />
&nbsp;&nbsp;&nbsp;&nbsp;B= &nbsp;|&nbsp; A&nbsp; A&nbsp; |<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp; O&nbsp; I&nbsp;&nbsp; |<br />
则B的乘方的结果其右上会是S，其他三个不变。此时化成了矩阵乘方问题，此时可以使用反复平方法，这样复杂度为(2n)^3*logk<br />
<br />
<br />
反复平方法，迭代版的， 以整数a^m为例：<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 alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />int <span style="color: #000000">pow(</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;m)<br />
<img id="Codehighlighter1_18_147_Open_Image" onclick="this.style.display='none'; Codehighlighter1_18_147_Open_Text.style.display='none'; Codehighlighter1_18_147_Closed_Image.style.display='inline'; Codehighlighter1_18_147_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_18_147_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_18_147_Closed_Text.style.display='none'; Codehighlighter1_18_147_Open_Image.style.display='inline'; Codehighlighter1_18_147_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_18_147_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_18_147_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;z&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(m&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_63_133_Open_Image" onclick="this.style.display='none'; Codehighlighter1_63_133_Open_Text.style.display='none'; Codehighlighter1_63_133_Closed_Image.style.display='inline'; Codehighlighter1_63_133_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_63_133_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_63_133_Closed_Text.style.display='none'; Codehighlighter1_63_133_Open_Image.style.display='inline'; Codehighlighter1_63_133_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;</span><span id="Codehighlighter1_63_133_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 alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_63_133_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;(n</span><span style="color: #000000">&amp;</span><span style="color: #000000">1</span><span style="color: #000000">)</span><span style="color: #000000">==</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;)&nbsp;y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;y*z</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;z&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;z&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;z;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;n&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 />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;y;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
递归的可以不用变量Z，要简单些，但是要注意了递归的调用顺序和结果的存储。<br />
<br />
<p>&nbsp;&nbsp; <img height="776" alt="" src="http://www.blogjava.net/images/blogjava_net/dongwq/ok.JPG" width="586" border="0" /></p>
<br /><img src ="http://www.blogjava.net/dongwq/aggbug/300791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-11-02 21:26 <a href="http://www.blogjava.net/dongwq/archive/2009/11/02/300791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最小表示法</title><link>http://www.blogjava.net/dongwq/archive/2009/11/02/300770.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 02 Nov 2009 10:13:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/11/02/300770.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300770.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/11/02/300770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300770.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300770.html</trackback:ping><description><![CDATA[<div class="postTitle"><a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cppblog.com/Uriel/articles/94573.html">POJ 1509 Glass Beads---最小表示法</a> zz</div>
<span style="font-size: 10.5pt; font-family: 宋体; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><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; font-family: Verdana; background-color: #eeeeee"><img id="Codehighlighter1_0_92_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_92_Open_Text.style.display='none'; Codehighlighter1_0_92_Closed_Image.style.display='inline'; Codehighlighter1_0_92_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_92_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_92_Closed_Text.style.display='none'; Codehighlighter1_0_92_Open_Image.style.display='inline'; Codehighlighter1_0_92_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_92_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">/**/</span><span id="Codehighlighter1_0_92_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">Problem:&nbsp;1509&nbsp;&nbsp;User:&nbsp;Uriel&nbsp;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;Memory:&nbsp;144K&nbsp;&nbsp;Time:&nbsp;16MS&nbsp;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;Language:&nbsp;C&nbsp;&nbsp;Result:&nbsp;Accepted</span><span style="color: #008000">*/</span></span><span style="color: #000000">&nbsp;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" />#include</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" />#include</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">string</span><span style="color: #000000">.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;min(</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)<br />
<img id="Codehighlighter1_156_182_Open_Image" onclick="this.style.display='none'; Codehighlighter1_156_182_Open_Text.style.display='none'; Codehighlighter1_156_182_Closed_Image.style.display='inline'; Codehighlighter1_156_182_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_156_182_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_156_182_Closed_Text.style.display='none'; Codehighlighter1_156_182_Open_Image.style.display='inline'; Codehighlighter1_156_182_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_156_182_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_156_182_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;a&nbsp;</span><span style="color: #000000">&lt;=</span><span style="color: #000000">&nbsp;b&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;a&nbsp;:&nbsp;b;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;MinimumRepresentation(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">s,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;l)<br />
<img id="Codehighlighter1_227_544_Open_Image" onclick="this.style.display='none'; Codehighlighter1_227_544_Open_Text.style.display='none'; Codehighlighter1_227_544_Closed_Image.style.display='inline'; Codehighlighter1_227_544_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_227_544_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_227_544_Closed_Text.style.display='none'; Codehighlighter1_227_544_Open_Image.style.display='inline'; Codehighlighter1_227_544_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_227_544_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_227_544_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&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;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;k&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;t;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;l&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;j&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;l&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;k&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;l)<br />
<img id="Codehighlighter1_301_521_Open_Image" onclick="this.style.display='none'; Codehighlighter1_301_521_Open_Text.style.display='none'; Codehighlighter1_301_521_Closed_Image.style.display='inline'; Codehighlighter1_301_521_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_301_521_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_301_521_Closed_Text.style.display='none'; Codehighlighter1_301_521_Open_Image.style.display='inline'; Codehighlighter1_301_521_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_301_521_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_301_521_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;s[(i&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;k)</span><span style="color: #000000">%</span><span style="color: #000000">l]&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;s[(j&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;k)</span><span style="color: #000000">%</span><span style="color: #000000">l];<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">!</span><span style="color: #000000">t)&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">&nbsp;k;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />
<img id="Codehighlighter1_387_515_Open_Image" onclick="this.style.display='none'; Codehighlighter1_387_515_Open_Text.style.display='none'; Codehighlighter1_387_515_Closed_Image.style.display='inline'; Codehighlighter1_387_515_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_387_515_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_387_515_Closed_Text.style.display='none'; Codehighlighter1_387_515_Open_Image.style.display='inline'; Codehighlighter1_387_515_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_387_515_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_387_515_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&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;</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&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;k&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;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;k&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&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;j)&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">j;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;min(i,j);<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x,len,i,t;<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;str[</span><span style="color: #000000">10010</span><span style="color: #000000">];<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()<br />
<img id="Codehighlighter1_590_779_Open_Image" onclick="this.style.display='none'; Codehighlighter1_590_779_Open_Text.style.display='none'; Codehighlighter1_590_779_Closed_Image.style.display='inline'; Codehighlighter1_590_779_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_590_779_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_590_779_Closed_Text.style.display='none'; Codehighlighter1_590_779_Open_Image.style.display='inline'; Codehighlighter1_590_779_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_590_779_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_590_779_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%d</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">&amp;</span><span style="color: #000000">t);<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;getchar();<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(t</span><span style="color: #000000">--</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_634_766_Open_Image" onclick="this.style.display='none'; Codehighlighter1_634_766_Open_Text.style.display='none'; Codehighlighter1_634_766_Closed_Image.style.display='inline'; Codehighlighter1_634_766_Closed_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_634_766_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_634_766_Closed_Text.style.display='none'; Codehighlighter1_634_766_Open_Image.style.display='inline'; Codehighlighter1_634_766_Open_Text.style.display='inline';" alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_634_766_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 alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_634_766_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(str,</span><span style="color: #000000">0x00</span><span style="color: #000000">,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(str));<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000">"</span><span style="color: #000000">%s</span><span style="color: #000000">"</span><span style="color: #000000">,str);<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">strlen(str);<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x</span><span style="color: #000000">=</span><span style="color: #000000">MinimumRepresentation(str,len);<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">%d\n</span><span style="color: #000000">"</span><span style="color: #000000">,x</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">);<br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top" />&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 />
<img alt="" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
</span></div>
<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"  alt="" /><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"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&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;isIsomorphism(String&nbsp;s1,&nbsp;String&nbsp;s2)<br />
<img id="Codehighlighter1_77_475_Open_Image" onclick="this.style.display='none'; Codehighlighter1_77_475_Open_Text.style.display='none'; Codehighlighter1_77_475_Closed_Image.style.display='inline'; Codehighlighter1_77_475_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_77_475_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_77_475_Closed_Text.style.display='none'; Codehighlighter1_77_475_Open_Image.style.display='inline'; Codehighlighter1_77_475_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_77_475_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"  alt="" /></span><span id="Codehighlighter1_77_475_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">[]&nbsp;u&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(s1</span><span style="color: #000000">+</span><span style="color: #000000">s1).toCharArray();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">[]&nbsp;w&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(s2</span><span style="color: #000000">+</span><span style="color: #000000">s2).toCharArray();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;s1.length();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;u.length&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;j&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;w.length)<br />
<img id="Codehighlighter1_245_456_Open_Image" onclick="this.style.display='none'; Codehighlighter1_245_456_Open_Text.style.display='none'; Codehighlighter1_245_456_Closed_Image.style.display='inline'; Codehighlighter1_245_456_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_245_456_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_245_456_Closed_Text.style.display='none'; Codehighlighter1_245_456_Open_Image.style.display='inline'; Codehighlighter1_245_456_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_245_456_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"  alt="" /></span><span id="Codehighlighter1_245_456_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&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;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">((i</span><span style="color: #000000">+</span><span style="color: #000000">k)&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;u.length&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;(j</span><span style="color: #000000">+</span><span style="color: #000000">k)</span><span style="color: #000000">&lt;</span><span style="color: #000000">u.length&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;u[i</span><span style="color: #000000">+</span><span style="color: #000000">k]&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;w[j</span><span style="color: #000000">+</span><span style="color: #000000">k])k</span><span style="color: #000000">++</span><span style="color: #000000">;</span><span style="color: #008000">//</span><span style="color: #008000">&amp;&amp;&nbsp;k&nbsp;&lt;&nbsp;len</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(k);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(k&nbsp;</span><span style="color: #000000">&gt;=</span><span style="color: #000000">&nbsp;len)&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 />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(u[i</span><span style="color: #000000">+</span><span style="color: #000000">k]&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;w[j</span><span style="color: #000000">+</span><span style="color: #000000">k])i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;i</span><span style="color: #000000">+</span><span style="color: #000000">k</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"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;j&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;j</span><span style="color: #000000">+</span><span style="color: #000000">k</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"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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 />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
</span><img src ="http://www.blogjava.net/dongwq/aggbug/300770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-11-02 18:13 <a href="http://www.blogjava.net/dongwq/archive/2009/11/02/300770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>排序算法、时间复杂度与信息熵 zz</title><link>http://www.blogjava.net/dongwq/archive/2009/11/02/300749.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 02 Nov 2009 08:19:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/11/02/300749.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300749.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/11/02/300749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300749.html</trackback:ping><description><![CDATA[<div style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin: 0px; width: 710px; padding-top: 0px; border-bottom: #4f5255 1px dotted"><span class="titles"><a title="Permanent Link to 排序算法、时间复杂度与信息熵" href="http://www.matrix67.com/blog/archives/529" rel="bookmark">排序算法、时间复杂度与信息熵</a></span>
<div><img style="margin-bottom: -3px" alt="icon2" src="http://www.matrix67.com/blog/wp-content/themes/CoolMist/images/icon2.gif" /> <a title="查看 Program Impossible 的全部文章" href="http://www.matrix67.com/blog/archives/category/program-impossible" rel="category tag">Program Impossible</a> | <img style="margin-bottom: -3px" alt="icon4" src="http://www.matrix67.com/blog/wp-content/themes/CoolMist/images/icon4.gif" /> 2008-05-30 13:23| <img style="margin-bottom: -3px" alt="icon3" src="http://www.matrix67.com/blog/wp-content/themes/CoolMist/images/icon3.gif" />17 Comments | 本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a> 转载请注明出自matrix67.com</div>
</div>
<div class="post">
<p>&nbsp;&nbsp;&nbsp;&nbsp;在<a href="http://www.matrix67.com/blog/archives/172">这篇文章</a>里，我们从信息论的角度证明了，基于比较的排序算法需要的比较次数（在最坏情况下）至少为log2(n!)，而log(n!)=&#920;(nlogn)，这给出了比较排序的一个下界。但那里我们讨论的只是最理想的情况。一个事件本身所含的信息量是有大小之分的。看到<a href="http://users.aims.ac.za/~mackay/sorting/sorting.html">这篇文章</a>之后，我的思路突然开阔了不少：信息论是非常强大的，它并不只是一个用来分析理论最优决策的工具。从信息论的角度来分析算法效率是一件很有趣的事，它给我们分析排序算法带来了一种新的思路。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;假如你手里有一枚硬币。你希望通过抛掷硬币的方法来决定今天晚上干什么，正面上网反面看电影。投掷硬币所产生的结果将给你带来一些&#8220;信息&#8221;，这些信息的多少就叫做&#8220;信息量&#8221;。如果这个硬币是&#8220;公正&#8221;的，正面和反面出现的概率一样，那么投掷硬币后不管结果咋样，你都获得了1 bit的信息量。如果你事先就已经知道这个硬币并不是均匀的，比如出现正面的概率本来就要大得多，这时我们就说事件结果的不确定性比刚才更小。如果投掷出来你发现硬币果然是正面朝上，这时你得到的信息量就相对更小（小于1 bit）；反之如果投掷出来居然反面朝上了，那你就得到了一个相对较大的信息量（大于1 bit）。但平均下来，我们得到的信息量是小于1 bit的，因为前者发生的可能性毕竟要大一些。最极端的情况就是，这是一枚被捣了鬼的魔术硬币，你怎么投都是正面。此时，你投了硬币等于没投，反正结果都是正面朝上，你得到的信息量永远为0。<br />
&nbsp;&nbsp;&nbsp;&nbsp;这个理论是很符合生活实际的。昨天晚上我出去吃饭时，坐在我后面的那个人是男的还是女的？这种问题就比较有价值，因为大家都猜不到答案究竟是什么；但要问我昨天跟谁一起出去上自习去了，问题的答案所含的信息量就变小了，因为大家都知道如果我破天荒地跑去自习了的话多半是有MM陪着一起去的。如果有网友问我是男的还是女的，那就更不可思议了，因为我不但多次在这个Blog里提到我一直想找一个合适的MM，还在AboutMe里面发了我的照片。如果某人刚操完一个MM，突然扭过头去问&#8220;对了，你是男的还是女的呀&#8221;，那这个人绝对是一个不折不扣的大傻B，因为这个问题所能带来的信息量几乎为0。<br />
&nbsp;&nbsp;&nbsp;&nbsp;总之，当每种结果出现的概率都相等，事件的不确定性达到最大，其结果最难预测时，事件的发生将会给我们带来最大的信息量。我们把一个事件的不确定程度叫做&#8220;熵&#8221;，熵越大表明这个事件的结果越难以预测，同时事件的发生将给我们带来越多的信息。如果在排序算法里每次比较的熵都是最大的，理论上来说这种（基于比较的）排序算法就应当是最优的。但我们一会儿将看到，我们已知的排序算法总是不完美的，每种算法都会或多或少地存在一些价值明显不大的比较。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;首先我们来看三种经典的平方复杂度算法。它们的效率并不高，原因就在于算法过程中会出现越来越多概率严重不均的比较。随着冒泡排序的进行，整个序列将变得越来越有序，位置颠倒的泡泡将越来越少；选择排序的每一趟选择中，你都会不断得到越来越大的数，同时在以后的比较中找到更大的数的概率也越来越低；在插入排序中，你总是把新的数与已经排好的数按从大到小的顺序依次进行比较，可以想到新的数一开始就比前面所有的数中最大的那个还大的概率是相当小的。受此启发，我们可以很自然地想到一个插入排序的改进：处理一个新的数时，为何不一开始就与前面处理过的数中的中位数进行比较？这种比较的熵显然更大，能获取的信息量要大得多，明显更有价值一些。这就是插入排序的二分查找改进。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;下面我们再来看一看几种O(nlogn)的排序算法。在快速排序算法中，比较的信息熵不会因为排序算法的进行而渐渐减小，这就是快速排序比上面几个排序算法更优秀的根本原因。仔细回顾快速排序算法的过程，我们立即看出，每次比较的两种结果出现的概率完全由这一趟划分过程所选择的基准关键字决定：选择的基准关键字刚好是当前处理的数字集合的中位数，则比较结果的不确定性达到最大；如果选择的基准关键字过大或过小，都会出现比较产生的结果不均等的情况，这使得每次比较平均带来的信息量大大减少。因此，快速排序算法是很看人品的：如果基准选的好，算法完全有可能达到理论上的最优；如果基准选的不好，复杂度很容易退化到O(n^2)。<br />
&nbsp;&nbsp;&nbsp;&nbsp;堆排序所需要的比较次数更多，因为在堆的删除操作中有一种明显不平衡的比较。在删除操作中，我们把根节点用整个堆的最末一个节点来代替，然后不断下沉直到它的儿子都比它大。判断它的两个儿子是否比它大，其信息熵是相当小的，因为这个节点本身就来自堆的底部，除非这个节点已经沉到很底下了，否则儿子比它大的概率是很小的。因此，我们想到了一个堆排序的优化：反正堆建好了以后不需要再插入新元素了，为何不舍弃堆的完全二叉树性质？我们可以直接把根元素改成无穷大，让它沉到底，不用再考虑儿子比它大的问题了，也不再顾及堆的形状。这样的话，堆排序是否就完美了呢？仔细想想你会发现，改进之后的比较操作仍然是不对称的。这种不对称主要来自两个方面：左子树和右子树的节点个数不同，以及被删除的根节点原先是来自左子树还是右子树。比方说，根节点原本就是从右子树提上来的，现在删除了根节点后，左子树的最小值比右子树的最小值更小的概率就偏大一些；此时万一右子树节点本来就比左边少，这样的话这个比较的熵就更小了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;最后看一下归并排序。在有序队列的合并操作中，绝大多数情况下的比较操作都是比较平衡的。左边一半中的最小值和右边一半中的最小值进行比较，结果显然是等概率的。当然，随后将发生其中一边的最小值与另一边的次小值进行比较，这时的比较操作略微有了一些不平衡，并存在较小的可能使得比较操作变得更加不平衡（最小值与第三小的值相比）。有趣的是，比较越是不平衡，重新归于平衡的概率就越大，就好像归并排序中的信息熵会自动调整一样。这就是归并排序比平方复杂度的排序算法效率更高的原因。当然，完全有可能出现这样的情况：右边的数奇小无比，左边的最小值比右边的所有值都大。结果最后右边的队列都处理完了左边还没开始取数，此时合并操作提前结束，所花费的比较次数出人意料地少。从信息熵的角度来看，这种&#8220;比较提前结束&#8221;的现象是非常自然的：这种情况毕竟是&#8220;出人意料&#8221;的，事实越出人意料，获得的信息量就越大，因此算法就提前结束了。但这种情况毕竟是相当罕见的，平均情况下每次比较的信息量仍然不足1 bit。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;最后，为什么线性排序的算法可以达到O(n)的复杂度？这是因为，线性排序算法并不是基于比较的。一次比较事件（假设没有相等的情况）所能产生的信息量最多1 bit，而一次Hash分类可以获得的信息量远远超过了1 bit，因为它可以一次确定出n种等概率的可能情况。</p>
<p>Matrix67原创，转贴请注明出处~~</p>
</div><img src ="http://www.blogjava.net/dongwq/aggbug/300749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-11-02 16:19 <a href="http://www.blogjava.net/dongwq/archive/2009/11/02/300749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>传说中效率最高的最大流算法(Dinic)  zz</title><link>http://www.blogjava.net/dongwq/archive/2009/10/30/300350.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Fri, 30 Oct 2009 06:37:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/30/300350.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300350.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/30/300350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300350.html</trackback:ping><description><![CDATA[<div id="topics">
<div class="post">
<h1 class="postTitle"><span style="color: #000000">传说中效率最高的最大流算法(Dinic) </span></h1>
<div class="postBody">
<p>呵呵,又从DK那偷代码了,好兴奋哈,以下是这个算法的简单介绍,不过我用它去解决HDU的1532 竟然TLE,郁闷.到时候再继续问问DK吧...so 烦躁.</p>
<p>哈哈 终于经过大牛的指点 原来本算法是从0开始标号的......</p>
<p>Dinic是个很神奇的网络流算法。它是一个基于&#8220;层次图&#8221;的时间效率优先的最大流算法。</p>
<p>层次图是什么东西呢？层次，其实就是从源点走到那个点的最短路径长度。于是乎，我们得到一个定理：从源点开始，在层次图中沿着边不管怎么走，经过的路径一定是终点在剩余图中的最短路。（摘自WC2007王欣上论文）注意，这里是要按照层次走。</p>
<p>那么，MPLA（最短路径增值）的一大堆复杂的证明我就略掉了，有兴趣的请自行参阅WC2007王欣上神牛的论文。</p>
<p>首先我们得知道，Dinic的基本算法步骤是，先算出剩余图，然后用剩余图算层次图，然后在层次图里找增广路。不知道你想到没有，这个层次图找增广路的方法，恰恰就是Ford-Fulkerson类算法的时间耗费最大的地方，就是找一个最短的增广路。所以呢，层次图就相当于是一个已经预处理好的增广路标志图。</p>
<p>如何实现Dinic呢？</p>
<p>首先我们必然要判一下有没有能到达终点的路径（判存在增广路与否），在这个过程中我们顺便就把层次图给算出来了（当然不用算完），然后就沿着层次图一层一层地找增广路；找到一条就进行增广（注意在沿着层次图找增广路的时候使用栈的结构，把路径压进栈）；增广完了继续找，找不到退栈，然后继续找有没有与这个结点相连的下一层结点，直到栈空。如果用递归实现，这个东西就很好办了，不过我下面提供的程序是用了模拟栈，当然这样就不存在结点数过多爆栈的问题了&#8230;&#8230;不过写起来也麻烦了一些，对于&#8220;继续找&#8221;这个过程我专门开了一个数组存当前搜索的指针。</p>
<p>上面拉拉杂杂说了一大堆，实际上在我的理解中，层次图就是一个流从高往低走的过程（这玩意儿有点像预流推进的标号法&#8230;&#8230;我觉得），在一条从高往低的路径中，自然有些地方会有分叉；这就是Dinic模拟栈中退栈的精华。这就把BFS的多次搜索给省略了不说，时间效率比所谓的理论复杂度要高得多。</p>
<p>这里有必要说到一点，网络流的时间复杂度都是很悲观的，一般情况下绝对没有可能到达那个复杂度的。</p>
<p>&nbsp;</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">#include</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br />
</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;maxn</span><span style="color: #000000">=</span><span style="color: #800080">300</span><span style="color: #000000">;<br />
</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;maxm</span><span style="color: #000000">=</span><span style="color: #800080">300000</span><span style="color: #000000">;<br />
</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;inf</span><span style="color: #000000">=</span><span style="color: #800080">0x7fffffff</span><span style="color: #000000">;<br />
</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;node<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;v,next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;val;<br />
}s[maxm</span><span style="color: #000000">*</span><span style="color: #800080">2</span><span style="color: #000000">];<br />
</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;level[maxn],p[maxn],que[maxn],</span><span style="color: #0000ff">out</span><span style="color: #000000">[maxn],ind;<br />
</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;init()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;ind</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;memset(p,</span><span style="color: #000000">-</span><span style="color: #800080">1</span><span style="color: #000000">,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(p));<br />
}<br />
inline&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;insert(long </span><span style="color: #000000">x,long</span><span style="color: #000000">&nbsp;y,long</span><span style="color: #000000">&nbsp;z)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].v</span><span style="color: #000000">=</span><span style="color: #000000">y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].val</span><span style="color: #000000">=</span><span style="color: #000000">z;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].next</span><span style="color: #000000">=</span><span style="color: #000000">p[x];<br />
&nbsp;&nbsp;&nbsp;&nbsp;p[x]</span><span style="color: #000000">=</span><span style="color: #000000">ind</span><span style="color: #000000">++</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].v</span><span style="color: #000000">=</span><span style="color: #000000">x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].val</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].next</span><span style="color: #000000">=</span><span style="color: #000000">p[y];<br />
&nbsp;&nbsp;&nbsp;&nbsp;p[y]</span><span style="color: #000000">=</span><span style="color: #000000">ind</span><span style="color: #000000">++</span><span style="color: #000000">;<br />
}<br />
inline&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;insert2(long</span><span style="color: #000000">&nbsp;x,long</span><span style="color: #000000">&nbsp;y,long</span><span style="color: #000000">&nbsp;z)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].v</span><span style="color: #000000">=</span><span style="color: #000000">y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].val</span><span style="color: #000000">=</span><span style="color: #000000">z;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].next</span><span style="color: #000000">=</span><span style="color: #000000">p[x];<br />
&nbsp;&nbsp;&nbsp;&nbsp;p[x]</span><span style="color: #000000">=</span><span style="color: #000000">ind</span><span style="color: #000000">++</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].v</span><span style="color: #000000">=</span><span style="color: #000000">x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].val</span><span style="color: #000000">=</span><span style="color: #000000">z;<br />
&nbsp;&nbsp;&nbsp;&nbsp;s[ind].next</span><span style="color: #000000">=</span><span style="color: #000000">p[y];<br />
&nbsp;&nbsp;&nbsp;&nbsp;p[y]</span><span style="color: #000000">=</span><span style="color: #000000">ind</span><span style="color: #000000">++</span><span style="color: #000000">;<br />
}<br />
</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;max_flow(</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;n,</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;source,</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;sink)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;long </span><span style="color: #000000">ret</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;long</span><span style="color: #000000">&nbsp;h</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">,r</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(</span><span style="color: #800080">1</span><span style="color: #000000">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(i</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">n;</span><span style="color: #000000">++</span><span style="color: #000000">i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;level[i]</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">,r</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;level[source]</span><span style="color: #000000">=</span><span style="color: #800080">1</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;que[</span><span style="color: #800080">0</span><span style="color: #000000">]</span><span style="color: #000000">=</span><span style="color: #000000">source;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(h</span><span style="color: #000000">&lt;=</span><span style="color: #000000">r)<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">long</span><span style="color: #000000">&nbsp;t</span><span style="color: #000000">=</span><span style="color: #000000">que[h</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">(i</span><span style="color: #000000">=</span><span style="color: #000000">p[t];i</span><span style="color: #000000">!=-</span><span style="color: #800080">1</span><span style="color: #000000">;i</span><span style="color: #000000">=</span><span style="color: #000000">s[i].next)<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">(s[i].val</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">level[s[i].v]</span><span style="color: #000000">==</span><span style="color: #800080">0</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;level[s[i].v]</span><span style="color: #000000">=</span><span style="color: #000000">level[t]</span><span style="color: #000000">+</span><span style="color: #800080">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;que[</span><span style="color: #000000">++</span><span style="color: #000000">r]</span><span style="color: #000000">=</span><span style="color: #000000">s[i].v;<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">if</span><span style="color: #000000">(level[sink]</span><span style="color: #000000">==</span><span style="color: #800080">0</span><span style="color: #000000">)</span><span style="color: #0000ff">break</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">(i</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">n;</span><span style="color: #000000">++</span><span style="color: #000000">i)</span><span style="color: #0000ff">out</span><span style="color: #000000">[i]</span><span style="color: #000000">=</span><span style="color: #000000">p[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;q</span><span style="color: #000000">=-</span><span style="color: #800080">1</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">(</span><span style="color: #800080">1</span><span style="color: #000000">)<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">(q</span><span style="color: #000000">&lt;</span><span style="color: #800080">0</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">long</span><span style="color: #000000">&nbsp;cur</span><span style="color: #000000">=</span><span style="color: #0000ff">out</span><span style="color: #000000">[source];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(;cur</span><span style="color: #000000">!=-</span><span style="color: #800080">1</span><span style="color: #000000">;cur</span><span style="color: #000000">=</span><span style="color: #000000">s[cur].next)<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;</span><span style="color: #0000ff">if</span><span style="color: #000000">(s[cur].val</span><span style="color: #000000">&amp;&amp;</span><span style="color: #0000ff">out</span><span style="color: #000000">[s[cur].v]</span><span style="color: #000000">!=-</span><span style="color: #800080">1</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">level[s[cur].v]</span><span style="color: #000000">==</span><span style="color: #800080">2</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;{<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;</span><span style="color: #0000ff">break</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;}<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">(cur</span><span style="color: #000000">&gt;=</span><span style="color: #800080">0</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;que[</span><span style="color: #000000">++</span><span style="color: #000000">q]</span><span style="color: #000000">=</span><span style="color: #000000">cur;<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">out</span><span style="color: #000000">[source]</span><span style="color: #000000">=</span><span style="color: #000000">s[cur].next;<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">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;</span><span style="color: #0000ff">break</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;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;u</span><span style="color: #000000">=</span><span style="color: #000000">s[que[q]].v;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(u</span><span style="color: #000000">==</span><span style="color: #000000">sink)<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">long</span><span style="color: #000000">&nbsp;dd</span><span style="color: #000000">=</span><span style="color: #000000">inf;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;index</span><span style="color: #000000">=-</span><span style="color: #800080">1</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">for</span><span style="color: #000000">(</span><span style="color: #000000">i</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;=</span><span style="color: #000000">q;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;{<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">(dd</span><span style="color: #000000">&gt;</span><span style="color: #000000">s[que[i]].val)<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;&nbsp;&nbsp;&nbsp;&nbsp;dd</span><span style="color: #000000">=</span><span style="color: #000000">s[que[i]].val;<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;index</span><span style="color: #000000">=</span><span style="color: #000000">i;<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;&nbsp;&nbsp;&nbsp;&nbsp;ret</span><span style="color: #000000">+=</span><span style="color: #000000">dd;<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">cout&lt;&lt;ret&lt;&lt;endl;</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">for</span><span style="color: #000000">(i</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;=</span><span style="color: #000000">q;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;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s[que[i]].val</span><span style="color: #000000">-=</span><span style="color: #000000">dd;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s[que[i]</span><span style="color: #000000">^</span><span style="color: #800080">1</span><span style="color: #000000">].val</span><span style="color: #000000">+=</span><span style="color: #000000">dd;&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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(i</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;=</span><span style="color: #000000">q;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;{<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">(s[que[i]].val</span><span style="color: #000000">==</span><span style="color: #800080">0</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;{<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;q</span><span style="color: #000000">=</span><span style="color: #000000">index</span><span style="color: #000000">-</span><span style="color: #800080">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;&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;&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;&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;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;cur</span><span style="color: #000000">=</span><span style="color: #0000ff">out</span><span style="color: #000000">[u];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(;cur</span><span style="color: #000000">!=-</span><span style="color: #800080">1</span><span style="color: #000000">;cur</span><span style="color: #000000">=</span><span style="color: #000000">s[cur].next)<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;</span><span style="color: #0000ff">if</span><span style="color: #000000">(s[cur].val</span><span style="color: #000000">&amp;&amp;</span><span style="color: #0000ff">out</span><span style="color: #000000">[s[cur].v]</span><span style="color: #000000">!=-</span><span style="color: #800080">1</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">level[u]</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">==</span><span style="color: #000000">level[s[cur].v])<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;&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(cur</span><span style="color: #000000">!=-</span><span style="color: #800080">1</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;que[</span><span style="color: #000000">++</span><span style="color: #000000">q]</span><span style="color: #000000">=</span><span style="color: #000000">cur;<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">out</span><span style="color: #000000">[u]</span><span style="color: #000000">=</span><span style="color: #000000">s[cur].next;<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">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;</span><span style="color: #0000ff">out</span><span style="color: #000000">[u]</span><span style="color: #000000">=-</span><span style="color: #800080">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;q</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;}<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;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;ret;<br />
}<br />
<br />
</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;m,n;<br />
<br />
</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()<br />
{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(scanf(</span><span style="color: #800000">"</span><span style="color: #800000">%ld&nbsp;%ld</span><span style="color: #800000">"</span><span style="color: #000000">,</span><span style="color: #000000">&amp;</span><span style="color: #000000">m,</span><span style="color: #000000">&amp;</span><span style="color: #000000">n)</span><span style="color: #000000">!=</span><span style="color: #000000">EOF)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init();<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: #800080">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">n;i</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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;from,to,cost;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #800000">"</span><span style="color: #800000">%ld&nbsp;%ld&nbsp;%ld</span><span style="color: #800000">"</span><span style="color: #000000">,</span><span style="color: #000000">&amp;</span><span style="color: #000000">from,</span><span style="color: #000000">&amp;</span><span style="color: #000000">to,</span><span style="color: #000000">&amp;</span><span style="color: #000000">cost);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(--from,--to,cost);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;Start,End;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #800000">"</span><span style="color: #800000">%ld&nbsp;%ld</span><span style="color: #800000">"</span><span style="color: #000000">,</span><span style="color: #000000">&amp;</span><span style="color: #000000">Start,</span><span style="color: #000000">&amp;</span><span style="color: #000000">End);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #800000">"</span><span style="color: #800000">%ld\n</span><span style="color: #800000">"</span><span style="color: #000000">,max_flow(n,--Start,--End));<br />
&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: #800080">0</span><span style="color: #000000">;<br />
}</span></div>
<div id="post_next_prev"><a href="http://www.cnblogs.com/zhuangli/archive/2008/08/03/1259248.html">&#171; </a>上一篇：<a title="发布于2008-08-03 15:39" href="http://www.cnblogs.com/zhuangli/archive/2008/08/03/1259248.html">KM算法(转)</a><a href="http://www.cnblogs.com/zhuangli/archive/2008/08/05/1260553.html">&#187; </a>下一篇：<a title="发布于2008-08-05 01:46" href="http://www.cnblogs.com/zhuangli/archive/2008/08/05/1260553.html">字典树</a><br />
</div>
<a href="http://www.cnblogs.com/zhuangli/category/147049.html"></a></div>
</div>
<img height="1" alt="" src="http://www.cnblogs.com/zhuangli/aggbug/1259527.html?type=1&amp;webview=1" width="1" /><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description rdf:about="http://www.cnblogs.com/zhuangli/archive/2008/08/04/1259527.html" dc:identifier="http://www.cnblogs.com/zhuangli/archive/2008/08/04/1259527.html" dc:title="" trackback:ping="http://www.cnblogs.com/zhuangli/services/trackbacks/1259527.aspx"  />
</rdf:RDF>
--></div>
<!--end: topics 文章、评论容器--><!--done--><img src ="http://www.blogjava.net/dongwq/aggbug/300350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-30 14:37 <a href="http://www.blogjava.net/dongwq/archive/2009/10/30/300350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最短路径 之 SPFA算法 zz</title><link>http://www.blogjava.net/dongwq/archive/2009/10/30/300339.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Fri, 30 Oct 2009 06:00:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/30/300339.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300339.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/30/300339.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300339.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300339.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最短路径&nbsp;之&nbsp;SPFA算法&nbsp;(转载）(2009-05-06 20:41:51)                        var $tag='spfa,杂谈';var $tag_code='0c0816ca8a11d99e776ffbef47dd2fd0';标签：spfa&nbsp;杂谈&nbsp;             ...&nbsp;&nbsp;<a href='http://www.blogjava.net/dongwq/archive/2009/10/30/300339.html'>阅读全文</a><img src ="http://www.blogjava.net/dongwq/aggbug/300339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-30 14:00 <a href="http://www.blogjava.net/dongwq/archive/2009/10/30/300339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言编一个简单的计算器</title><link>http://www.blogjava.net/dongwq/archive/2009/10/30/300286.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Thu, 29 Oct 2009 16:36:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/30/300286.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300286.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/30/300286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300286.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300286.html</trackback:ping><description><![CDATA[#include&nbsp; &lt;stdio.h&gt;<br />
int add(int x,int y)&nbsp; {return x+y;}<br />
int sub(int x,int y)&nbsp; {return x-y;}<br />
int mul(int x,int y)&nbsp; {return x*y;}<br />
int div(int x,int y)&nbsp; {return x/y;}<br />
int (*func[])()={add,sub,mul,div};<br />
int num,curch;<br />
char chtbl[]="+-*/()=";<br />
char corch[]="+-*/()=0123456789";<br />
int getach()&nbsp; {<br />
&nbsp;&nbsp;&nbsp; int i;<br />
&nbsp;&nbsp;&nbsp; while(1)&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; curch=getchar();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(curch==EOF)&nbsp; return -1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;corch[i]&amp;&amp;curch!=corch[i];i++);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i&lt;strlen(corch))&nbsp; break;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return curch;<br />
}<br />
<br />
int getid()&nbsp; {<br />
&nbsp;&nbsp;&nbsp; int i;<br />
&nbsp;&nbsp;&nbsp; if(curch&gt;='0'&amp;&amp;curch&lt;='9')&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(num=0;curch&gt;='0'&amp;&amp;curch&lt;='9';getach())&nbsp;&nbsp;&nbsp; num=10*num+curch-'0';<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; else&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;chtbl[i];i++) if(chtbl[i]==curch)&nbsp; break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i&lt;=5)&nbsp; getach();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i;<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
int cal()&nbsp; {<br />
&nbsp;&nbsp;&nbsp; int x1,x2,x3,op1,op2,i;<br />
&nbsp;&nbsp;&nbsp; i=getid();<br />
&nbsp;&nbsp;&nbsp; if(i==4)&nbsp;&nbsp;&nbsp; x1=cal();&nbsp;&nbsp;&nbsp; else&nbsp; x1=num;<br />
&nbsp;&nbsp;&nbsp; op1=getid();<br />
&nbsp;&nbsp;&nbsp; if(op1&gt;=5)&nbsp; return x1;<br />
&nbsp;&nbsp;&nbsp; i=getid();<br />
&nbsp;&nbsp;&nbsp; if(i==4)&nbsp; x2=cal();&nbsp;&nbsp;&nbsp; else&nbsp; x2=num;<br />
&nbsp;&nbsp;&nbsp; op2=getid();<br />
&nbsp;&nbsp;&nbsp; while(op2&lt;=4)&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i=getid();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i==4)&nbsp; x3=cal();&nbsp; else&nbsp; x3=num;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((op1/2==0)&amp;&amp;(op2/2==1))&nbsp;&nbsp;&nbsp; x2=(*func[op2])(x2,x3);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x1=(*func[op1])(x1,x2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x2=x3;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; op1=op2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; op2=getid();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return (*func[op1])(x1,x2);<br />
}<br />
<br />
void main(void)&nbsp; {<br />
&nbsp;&nbsp;&nbsp; int value;<br />
&nbsp;&nbsp;&nbsp; printf("Please input an expression:\n");<br />
&nbsp;&nbsp;&nbsp; getach();<br />
&nbsp;&nbsp;&nbsp; while(curch!='=')&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value=cal();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("The result is:%d\n",value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Please input an expression:\n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getach();<br />
&nbsp;&nbsp;&nbsp; }<br />
} <br /><img src ="http://www.blogjava.net/dongwq/aggbug/300286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-30 00:36 <a href="http://www.blogjava.net/dongwq/archive/2009/10/30/300286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于C++中函数指针的使用(包含对typedef用法的讨论) </title><link>http://www.blogjava.net/dongwq/archive/2009/10/30/300285.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Thu, 29 Oct 2009 16:35:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/30/300285.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300285.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/30/300285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300285.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300285.html</trackback:ping><description><![CDATA[<strong><font size="4">（一）简单的函数指针的应用。</font></strong><br />
<font color="#00ff00">//形式1：返回类型(*函数名)(参数表)</font> <br />
<strong>char (*pFun)(int); <br />
char glFun(int a){ return;} <br />
void main() <br />
{ <br />
&nbsp;&nbsp;&nbsp; pFun = glFun; <br />
&nbsp;&nbsp;&nbsp; (*pFun)(2); <br />
}</strong> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;第一行定义了一个指针变量pFun。首先我们根据前面提到的&#8220;形式1&#8221;认识到它是一个指向某种函数的指针，这种函数参数是一个int型，返回值是char类型。只有第一句我们还无法使用这个指针，因为我们还未对它进行赋值。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 第二行定义了一个函数glFun()。该函数正好是一个以int为参数返回char的函数。我们要从指针的层次上理解函数——函数的函数名实际上就是一个指针，函数名指向该函数的代码在内存中的首地址。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 然后就是可爱的main()函数了，它的第一句您应该看得懂了——它将函数glFun的地址赋值给变量pFun。main()函数的第二句中&#8220;*pFun&#8221;显然是取pFun所指向地址的内容，当然也就是取出了函数glFun()的内容，然后给定参数为2。<br />
<font size="4"><strong>（二）使用typedef更直观更方便。</strong></font> <br />
<font color="#00ff00">//形式2：typedef 返回类型(*新类型)(参数表)</font><br />
<strong>typedef char (*PTRFUN)(int); <br />
PTRFUN pFun; <br />
char glFun(int a){ return;} <br />
void main() <br />
{ <br />
&nbsp;&nbsp;&nbsp; pFun = glFun; <br />
&nbsp;&nbsp;&nbsp; (*pFun)(2); <br />
}</strong> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef的功能是定义新的类型。第一句就是定义了一种PTRFUN的类型，并定义这种类型为指向某种函数的指针，这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二行的代码便使用这个新类型定义了变量pFun，此时就可以像使用形式1一样使用这个变量了。<br />
<strong><font size="4">（三）在C++类中使用函数指针。</font></strong> <br />
<font style="background-color: rgb(0,0,0)" color="#00ff00"><font style="background-color: rgb(255,255,255)">//形式3：typedef 返回类型(类名::*新类型)(参数表)</font><font style="background-color: rgb(255,255,255)"> <br />
</font></font><strong>class CA<br />
{<br />
&nbsp;public: <br />
&nbsp;&nbsp;&nbsp; char lcFun(int a){ return; } <br />
}; <br />
CA ca;<br />
typedef char (CA::*PTRFUN)(int); <br />
PTRFUN pFun; <br />
void main() <br />
{ <br />
&nbsp;&nbsp;&nbsp; pFun = CA::lcFun; <br />
&nbsp;&nbsp;&nbsp; ca.(*pFun)(2); <br />
}</strong> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这里，指针的定义与使用都加上了&#8220;类限制&#8221;或&#8220;对象&#8221;，用来指明指针指向的函数是那个类的这里的类对象也可以是使用new得到的。比如： <br />
<strong>CA *pca = new CA; <br />
pca-&gt;(*pFun)(2); <br />
delete pca;</strong> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而且这个类对象指针可以是类内部成员变量，你甚至可以使用this指针。比如：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类CA有成员变量PTRFUN m_pfun; <br />
<strong>void CA::lcFun2() <br />
{&nbsp;<br />
&nbsp;&nbsp; (this-&gt;*m_pFun)(2);<br />
}</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一句话，使用类成员函数指针必须有&#8220;-&gt;*&#8221;或&#8220;.*&#8221;的调用。
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>作者:csumck &nbsp; 更新日期:2004-11-07<br />
来源:CSDN &nbsp; 浏览次数: <script src="http://www.upsdn.net/view.php?id=40" type="text/javascript"></script></p><img src ="http://www.blogjava.net/dongwq/aggbug/300285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-30 00:35 <a href="http://www.blogjava.net/dongwq/archive/2009/10/30/300285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>系统的可靠度计算公式 收藏 </title><link>http://www.blogjava.net/dongwq/archive/2009/10/29/300143.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Thu, 29 Oct 2009 03:05:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/29/300143.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300143.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/29/300143.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300143.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300143.html</trackback:ping><description><![CDATA[<p>系统的可靠度计算公式 收藏 <br />
并联:1-(1-p1)(1-p2)</p>
<p><br />
串联:p1p2</p>
<p><br />
p1,p2分别为部件1和部件2的可靠度.<br />
---------------------------------------------------------------------------<br />
eg:<br />
某计算机系统的可靠性结构是如下图所示的双重串并联结构，若所构成系统的每个部件的可靠度为0.9 ，即R=0.9 ，则系统的可靠度为（）？ </p>
<p>|－－－（R）————（R）－－－| <br />
———| |－－ <br />
|－－－（R）－－－－（R）－－－| </p>
<p>类似于串两个电阻，在并两个电阻的图。问怎样计算？ <br />
&nbsp;<br />
最佳答案<br />
串联的可靠度P1=R1&#215;R1 =0.81 <br />
并联起来时可靠度P2=1-（1-P1）&#215;（1-P1）=0.9639 </p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/zwhfyy/archive/2009/04/02/4042513.aspx</p><img src ="http://www.blogjava.net/dongwq/aggbug/300143.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-29 11:05 <a href="http://www.blogjava.net/dongwq/archive/2009/10/29/300143.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>背包问题 ZZ</title><link>http://www.blogjava.net/dongwq/archive/2009/10/28/300104.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Wed, 28 Oct 2009 13:01:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/28/300104.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/300104.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/28/300104.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/300104.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/300104.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 背包问题 1.引子&nbsp; 我们人类是一种贪婪的动物，如果给您一个容量一定的背包和一些大小不一的物品，裝到背包里面的物品就归您，遇到这种好事大家一定不会错过，用力塞不一定是最好的办法，用脑子才行，下面就教您如何解决这样的问题，以获得更多的奖品。2.应用场景&nbsp; 在一个物品向量中找到一个子集满足条件如下 ：&nbsp;&nbsp; 1）这个子集加起来的体积大小不能...&nbsp;&nbsp;<a href='http://www.blogjava.net/dongwq/archive/2009/10/28/300104.html'>阅读全文</a><img src ="http://www.blogjava.net/dongwq/aggbug/300104.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-28 21:01 <a href="http://www.blogjava.net/dongwq/archive/2009/10/28/300104.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SBT (转载）</title><link>http://www.blogjava.net/dongwq/archive/2009/10/28/299996.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Tue, 27 Oct 2009 17:07:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/28/299996.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299996.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/28/299996.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299996.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299996.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt"><span style="font-family: 宋体">在今年的信息学冬令营上，陈启峰提出了一个自己创造的</span>BST<span style="font-family: 宋体">数据结构</span>—Size Balanced Tree<span style="font-family: 宋体">。这个平衡二叉树被全世界内的许多网站所讨论，大家讨论的主题也只有一个</span>—SBT<span style="font-family: 宋体">能够取代</span>Treap<span style="font-family: 宋体">吗？本文详细介绍</span>SBT<span style="font-family: 宋体">树的性质，以及一些常用的操作，最后证明</span>SBT<span style="font-family: 宋体">是一颗高度平衡的二分查找树。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt"><strong><span style="font-size: 14pt">一．<span style="font: 7pt 'Times new roman'; font-size-adjust: none; font-stretch: normal">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span></span></strong> <strong><span style="font-size: 14pt; font-family: 宋体">介绍</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">众所周知，</span>BST<span style="font-family: 宋体">能够快速的实现查找等动态操作。但是在某些情况下，比如将一个有序的序列依次插入到</span>BST<span style="font-family: 宋体">中，则</span>BST<span style="font-family: 宋体">会退化成为一条链，效率非常之低。由此引申出来很多平衡</span>BST<span style="font-family: 宋体">，比如</span>AVL<span style="font-family: 宋体">树，红黑树，</span>treap<span style="font-family: 宋体">树等。这些数据结构都是通过引入其他一些性质来保证</span>BST<span style="font-family: 宋体">的高度在最坏的情况下都保持在</span>O(log n)<span style="font-family: 宋体">。其中</span>,AVL<span style="font-family: 宋体">树和红黑树的很多操作都非常麻烦，因此实际应用不是很多。而</span>treap<span style="font-family: 宋体">树加入了一些随机化堆的性质，实际应用效果非常好，实现起来很简单，一直以来受到很多人的青睐。本文介绍一种新的平衡</span>BST<span style="font-family: 宋体">树，实现起来也是非常之简单，并且能够支持更多的操作，实际评测效率跟</span>treap<span style="font-family: 宋体">也不差上下。</span></p>
<p style="margin-left: 21pt"><span style="font-family: 宋体">在介绍</span>SBT<span style="font-family: 宋体">之前，先介绍一下</span>BST<span style="font-family: 宋体">以及在</span>BST<span style="font-family: 宋体">上的旋转操作。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt"><strong><span style="font-size: 12pt">1.<span style="font: 7pt 'Times new roman'; font-size-adjust: none; font-stretch: normal">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span></span></strong> <strong><span style="font-size: 12pt">Binary Search Tree</span></strong></p>
<p style="text-indent: 21pt">BST<span style="font-family: 宋体">是一种高级的数据结构，它支持很多动态操作，包括查找，求最小值，最大值，前驱，后继，插入和删除，能够用于字典以及优先队列。</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> BST<span style="font-family: 宋体">是一棵二叉树，每个结点最多有</span>2<span style="font-family: 宋体">个儿子。每个结点都有个键值，并且键值必须满足下面的条件：</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">如果</span>x<span style="font-family: 宋体">是</span>BST<span style="font-family: 宋体">中的一个结点。那么</span>x<span style="font-family: 宋体">的键值不小于其左儿子的键值，并且不大于其右儿子的键值。</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">对于每个结点</span>t<span style="font-family: 宋体">，用</span>left[t]<span style="font-family: 宋体">和</span>right[t]<span style="font-family: 宋体">分别来存放它的两个儿子，</span>ket[t]<span style="font-family: 宋体">存放该结点的键值。另外，在</span>SBT<span style="font-family: 宋体">中，要增加</span>s[t],<span style="font-family: 宋体">用来保存以</span>t<span style="font-family: 宋体">为根的子树中结点的个数。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt"><strong><span style="font-size: 12pt">2.<span style="font: 7pt 'Times new roman'; font-size-adjust: none; font-stretch: normal">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span></span></strong> <strong><span style="font-size: 12pt; font-family: 宋体">旋转</span></strong></p>
<p style="margin-left: 21pt"><span style="font-family: 宋体">为了保证</span>BST<span style="font-family: 宋体">的平衡</span>(<span style="font-family: 宋体">不会退化成为一条链</span>)<span style="font-family: 宋体">，通常通过旋转操作来改变</span>BST<span style="font-family: 宋体">的结构。旋转操作不会影响</span>binary-search-tree<span style="font-family: 宋体">的性质！</span></p>
<p style="margin-left: 21pt"><span style="font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/1.jpg" border="0" /><br />
</span></p>
<p style="margin-left: 21pt">&nbsp;<wbr></p>
<p><strong><span style="font-size: 12pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 2.1</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">右旋操作的伪代码</span></strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">右旋操作必须保证左儿子存在</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Right-Rotate(t)</p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> k&#8592;left[t]</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> left[t]&#8592;right[k]</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> right[k]&#8592;t</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s[k]&#8592;s[t]</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s[t]&#8592;s[left[t]]+s[right[t]]+1</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> t&#8592;k</span></p>
<p><strong>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 2.2</strong> <strong><span style="font-family: 宋体">左旋操作的伪代码</span></strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-size: 10.5pt; font-family: 宋体">左旋操作必须保证右儿子存在</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Left-Rotate(t)</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> k&#8592;right[t]</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> right[t]&#8592;left[k]</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> left[k]&#8592;t</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s[k]&#8592;s[t]</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s[t]&#8592;s[left[t]]+s[right[t]]+1</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> t&#8592;k<br />
<br />
</p>
<div class="articleContent" id="articleBody">
<p><strong><span style="font-family: 宋体">二．</span>Size Balanced Tree</strong></p>
<p style="text-indent: 21pt"><span style="font-size: 10.5pt">Size Balanced Tree(</span><span style="font-size: 10.5pt; font-family: 宋体">简称</span><span style="font-size: 10.5pt">SBT)</span><span style="font-size: 10.5pt; font-family: 宋体">是一种平衡二叉搜索树，它通过子树的大小</span><span style="font-size: 10.5pt">s[t]</span><span style="font-size: 10.5pt; font-family: 宋体">来维持平衡性质。它支持很多动态操作，并且都能够在</span><span style="font-size: 10.5pt">O(log n)</span><span style="font-size: 10.5pt; font-family: 宋体">的时间内完成。</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Insert(t,v)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">将键值为</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">的结点插入到根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Delete(t,v)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">在根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中删除键值为</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">的结点</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Find(t,v)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">在根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中查找键值为</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">的结点</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Rank(t,v)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">返回根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中键值</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">的排名。也就是树中键值比</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">小的结点数</span><span style="font-size: 10.5pt">+1</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Select(t,k)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">返回根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中排名为</span><span style="font-size: 10.5pt">k</span><span style="font-size: 10.5pt; font-family: 宋体">的结点。同时该操作能够实现</span><span style="font-size: 10.5pt">Get-min,Get-max,</span><span style="font-size: 10.5pt; font-family: 宋体">因为</span><span style="font-size: 10.5pt">Get-min</span><span style="font-size: 10.5pt; font-family: 宋体">等于</span><span style="font-size: 10.5pt">Select(t,1),Get-max</span><span style="font-size: 10.5pt; font-family: 宋体">等于</span><span style="font-size: 10.5pt">Select(t,s[t])</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Pred(t,v)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">返回根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中比</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">小的最大的键值</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 86.4pt; padding-top: 0cm" valign="top" width="115">
            <p style="text-align: justify"><span style="font-size: 10.5pt">Succ(t,v)</span></p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 339.7pt; padding-top: 0cm" valign="top" width="453">
            <p style="text-align: justify"><span style="font-size: 10.5pt; font-family: 宋体">返回根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的树中比</span><span style="font-size: 10.5pt">v</span><span style="font-size: 10.5pt; font-family: 宋体">大的最小的键值</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-indent: 21pt"><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">树中的每个结点都有</span><span style="font-size: 10.5pt">left</span><span style="font-size: 10.5pt; font-family: 宋体">，</span><span style="font-size: 10.5pt">right</span><span style="font-size: 10.5pt; font-family: 宋体">，</span><span style="font-size: 10.5pt">key</span><span style="font-size: 10.5pt; font-family: 宋体">以及前面提到的</span><span style="font-size: 10.5pt">size</span><span style="font-size: 10.5pt; font-family: 宋体">域。</span><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">能够保持平衡性质是因为其必须满足下面两个条件：</span></p>
<p style="text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 宋体">对于</span><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">中的每个结点</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">，有性质</span><span style="font-size: 10.5pt">(a)(b)</span><span style="font-size: 10.5pt; font-family: 宋体">：</span></p>
<p><span style="font-size: 10.5pt">(a). s[right[t]</span><span style="font-size: 10.5pt; font-family: 宋体">]</span><span style="font-size: 10.5pt; font-family: 宋体">&#8805;s[left[left[t]]],s[right[left[t]]]</span></p>
<p><span style="font-size: 10.5pt">(b). s[left[t]]</span><span style="font-size: 10.5pt; font-family: 宋体">&#8805;s[right[right[t]]],s[left[right[t]]]</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c2.jpg" border="0" /><br />
</span></p>
<p>&nbsp;<wbr></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">即在上图中，有</span><span style="font-size: 10.5pt">s[A],s[B</span><span style="font-size: 10.5pt; font-family: 宋体">]</span><span style="font-size: 10.5pt; font-family: 宋体">&#8804;s[R]&amp;s[C],s[D] &#8804;s[L]</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><strong><span style="font-size: 14pt; font-family: 宋体">三.<span style="font: 7pt 'Times new roman'; font-size-adjust: none; font-stretch: normal">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span></span></strong> <strong><span style="font-size: 14pt; font-family: 宋体">&nbsp;<wbr>Maintain</span></strong></p>
<p style="text-indent: 18pt"><span style="font-size: 10.5pt; font-family: 宋体">假设我们要在BST中插入一个键值为v的结点，一般是用下面这个过程：</span></p>
<p style="text-indent: 18pt"><span style="font-size: 10.5pt; font-family: 宋体">Simple-Insert(t,v)</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> If t=0 then</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> t</span><span style="font-size: 10.5pt">&#8592;NEW-NODE(v)</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Else</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s[t]&#8592;s[t]+1</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> If v&lt;key[t] then</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Simple-Insert(left[t],v)</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Else</span></p>
<p><span style="font-size: 10.5pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Simple-Insert(right[t],v)</span></p>
<p style="text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 宋体">执行完操作</span><span style="font-size: 10.5pt">Simple-Insert</span><span style="font-size: 10.5pt; font-family: 宋体">后，</span><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">的性质</span><span style="font-size: 10.5pt">(a)</span><span style="font-size: 10.5pt; font-family: 宋体">和</span><span style="font-size: 10.5pt">(b)</span><span style="font-size: 10.5pt; font-family: 宋体">就有可能不满足了，这是我们就需要修复</span><span style="font-size: 10.5pt">(Maintain)SBT</span><span style="font-size: 10.5pt; font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-size: 10.5pt">Maintain(t)</span><span style="font-size: 10.5pt; font-family: 宋体">用来修复根为</span><span style="font-size: 10.5pt">t</span><span style="font-size: 10.5pt; font-family: 宋体">的</span><span style="font-size: 10.5pt">SBT,</span><span style="font-size: 10.5pt; font-family: 宋体">使其满足</span><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">性质。由于性质</span><span style="font-size: 10.5pt">(a)</span><span style="font-size: 10.5pt; font-family: 宋体">和</span><span style="font-size: 10.5pt">(b)</span><span style="font-size: 10.5pt; font-family: 宋体">是对称的，下面仅讨论对性质</span><span style="font-size: 10.5pt">(a)</span><span style="font-size: 10.5pt; font-family: 宋体">的修复。</span></p>
<p><strong><span style="font-size: 10.5pt">Case 1</span></strong><span style="font-size: 10.5pt; font-family: 宋体">：</span><span style="font-size: 10.5pt">s[left[left[t]]]&gt;s[right[t]]</span></p>
<p><span style="font-size: 10.5pt"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c3.jpg" border="0" /><br />
</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">这种情况下可以执行下面的操作来修复</span><span style="font-size: 10.5pt">SBT</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体">执行</span><span style="font-size: 10.5pt">Right-Rotate(T)</span></p>
<p style="text-align: center" align="center">&nbsp;<wbr></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体">有可能旋转后的树仍然不是</span><span style="font-size: 10.5pt">SBT,</span><span style="font-size: 10.5pt; font-family: 宋体">需要再次执行</span><span style="font-size: 10.5pt">Maintain(T)</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体">由于</span><span style="font-size: 10.5pt">L</span><span style="font-size: 10.5pt; font-family: 宋体">的右儿子发生了变化，因此需要执行</span><span style="font-size: 10.5pt">Maintain(L)</span></p>
<p><strong><span style="font-size: 10.5pt">Case 2</span></strong><span style="font-size: 10.5pt; font-family: 宋体">：</span><span style="font-size: 10.5pt">s[right[left[t]]]&gt;s[right[t]]</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">这种情况如下图所示：</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c4.jpg" border="0" /><br />
</span></p>
<p style="text-align: center" align="center">&nbsp;<wbr></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">需要执行一下步骤来修复</span><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">：</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体">执行</span><span style="font-size: 10.5pt">Left-Rotate(L)</span><span style="font-size: 10.5pt; font-family: 宋体">。如下图所示</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c5.jpg" border="0" /><br />
</span></p>
<p style="text-align: center" align="center">&nbsp;<wbr></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体">执行</span><span style="font-size: 10.5pt">Right-Rotate(T)</span><span style="font-size: 10.5pt; font-family: 宋体">。如下图所示</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c6.jpg" border="0" /><br />
</span></p>
<p style="text-align: center" align="center">&nbsp;<wbr></p>
<p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10.5pt; font-family: 宋体">当执行完</span><span style="font-size: 10.5pt">(1)(2)</span><span style="font-size: 10.5pt; font-family: 宋体">后，树的结构变得不可预测了。但是幸运的是，在上图中，</span><span style="font-size: 10.5pt">A,E,F,R</span><span style="font-size: 10.5pt; font-family: 宋体">子树仍然是</span><span style="font-size: 10.5pt">SBT</span><span style="font-size: 10.5pt; font-family: 宋体">。因此我们可以执行</span><span style="font-size: 10.5pt">Maintain(L)</span><span style="font-size: 10.5pt; font-family: 宋体">和</span><span style="font-size: 10.5pt">Maintain(T)</span><span style="font-size: 10.5pt; font-family: 宋体">来修复</span><span style="font-size: 10.5pt">B</span><span style="font-size: 10.5pt; font-family: 宋体">的子树。</span></p>
<p><strong>Case 3</strong><span style="font-family: 宋体">：</span></p>
<p><span style="font-family: 宋体">这种情况和</span>case 1<span style="font-family: 宋体">是对称的</span></p>
<p><strong>Case 4</strong><span style="font-family: 宋体">：</span></p>
<p><span style="font-family: 宋体">这种情况和</span>case 2<span style="font-family: 宋体">是对称的</span></p>
<p><span style="font-size: 10.5pt">Maintain</span><span style="font-size: 10.5pt; font-family: 宋体">操作的伪代码：</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">在</span><span style="font-size: 10.5pt">Maintain</span><span style="font-size: 10.5pt; font-family: 宋体">过程中，用一个变量</span><span style="font-size: 10.5pt">flag</span><span style="font-size: 10.5pt; font-family: 宋体">来避免额外的检查。当</span><span style="font-size: 10.5pt">flag</span><span style="font-size: 10.5pt; font-family: 宋体">为</span><span style="font-size: 10.5pt">false</span><span style="font-size: 10.5pt; font-family: 宋体">时，代表</span><span style="font-size: 10.5pt">case 1</span><span style="font-size: 10.5pt; font-family: 宋体">和</span><span style="font-size: 10.5pt">case 2</span><span style="font-size: 10.5pt; font-family: 宋体">需要被检查</span><span style="font-size: 10.5pt">,</span><span style="font-size: 10.5pt; font-family: 宋体">否则</span><span style="font-size: 10.5pt">case 3</span><span style="font-size: 10.5pt; font-family: 宋体">和</span><span style="font-size: 10.5pt">case 4</span><span style="font-size: 10.5pt; font-family: 宋体">需要被检查。</span></p>
<p><span style="color: black">Maintain (t,flag)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="color: black">If</span></strong> <span style="color: black">flag=false <strong>then</strong></span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>If</strong> s[left[left[t]]&gt;s[right[t]] <strong>then</strong></span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Right-Rotate(t)</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Elseif</strong> s[right[left[t]]&gt;s[right[t]] <strong>then</strong></span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Left-Rotate(left[t])</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Right-Rotate(t)</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Else</strong> exit</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Elseif</strong> s[right[right[t]]&gt;s[left[t]] <strong>then</strong></span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Left-Rotate(t)</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Elseif</strong> s[left[right[t]]&gt;s[left[t]] <strong>then</strong></span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Right-Rotate(right[t])</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Left-Rotate(t)</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Else</strong> exit</span></p>
<p style="text-align: left" align="left"><span style="color: black">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Maintain(left[t],false)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><span style="color: black">Maintain(right[t],true)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><span style="color: black">Maintain(t,false)</span></p>
<p style="text-align: left" align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Maintain(t,true)</p>
</div>
<p><strong><span style="font-size: 14pt; font-family: 宋体">四．常用操作</span></strong></p>
<p style="margin-left: 18pt; text-indent: -18pt"><strong><span style="font-size: 12pt; font-family: 宋体">插入操作</span></strong></p>
<p>SBT<span style="font-family: 宋体">和插入操作和</span>BST<span style="font-family: 宋体">的基本相同，只是在插入之后需要执行下</span>Maintain<span style="font-family: 宋体">操作。</span></p>
<p><span style="font-size: 11.5pt; color: black">Insert (t,v)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="font-size: 11.5pt; color: black">If</span></strong> <span style="font-size: 11.5pt; color: black">t=0 <strong>then</strong></span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="font-size: 11.5pt; color: black">t&#8592;NEW-NODE(v)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="font-size: 11.5pt; color: black">Else</span></strong></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="font-size: 11.5pt; color: black">s[t] &#8592;s[t]+1</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="font-size: 11.5pt; color: black">If</span></strong> <span style="font-size: 11.5pt; color: black">v&lt;key[t] <strong>then</strong></span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="font-size: 11.5pt; color: black">Simple-Insert(left[t],v)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="font-size: 11.5pt; color: black">Else</span></strong></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="font-size: 11.5pt; color: black">Simple-Insert(right[t],v)</span></p>
<p style="text-indent: 18pt; text-align: left" align="left"><span style="font-size: 11.5pt; color: black">Maintain(t,v&#8805;key[t])</span></p>
<p style="margin-left: 18pt; text-indent: -18pt"><strong><span style="font-size: 12pt; font-family: 宋体">删除操作</span></strong></p>
<p><span style="font-family: 宋体">如果没有找到要删除的结点，那么就删除最后一个访问的结点并记录。</span></p>
<p><span style="color: black">Delete (t,v)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="color: black">If</span></strong> <span style="color: black">s[t]</span><span style="color: black; font-family: 黑体">&#8804;</span><span style="color: black">2 <strong>then</strong></span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="color: black">record&#8592;key[t]</span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="color: black">t&#8592;left[t]+right[t]</span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="color: black">Exit</span></p>
<p style="margin-left: 21pt; text-align: left" align="left"><span style="color: black">s[t] &#8592;s[t]</span><span style="color: black; font-family: 黑体">－</span><span style="color: black">1</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong><span style="color: black">If</span></strong> <span style="color: black">v=key[t] <strong>then</strong></span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="color: black">Delete(left[t],v[t]+1)</span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="color: black">Key[t] &#8592;record</span></p>
<p style="margin-left: 21pt; text-indent: 21pt; text-align: left" align="left"><span style="color: black">Maintain(t,true)</span></p>
<p style="text-indent: 21pt; text-align: left" align="left"><strong>Else</strong></p>
<p style="margin-left: 21pt; text-indent: 21pt"><strong><span style="font-size: 10.5pt">If</span></strong> <span style="font-size: 10.5pt">v&lt;key[t] <strong>then</strong></span></p>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-size: 10.5pt">Delete(left[t],v)</span></p>
<p style="text-indent: 21pt"><strong><span style="font-size: 10.5pt">Else</span></strong></p>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-size: 10.5pt">Delete(right[t],v)</span></p>
<p style="text-indent: 21pt"><span style="font-size: 10.5pt">Maintain(t,v&lt;key[t])</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">另外，由于</span>SBT<span style="font-family: 宋体">的平衡性质是靠</span>size<span style="font-family: 宋体">域来维护的，而</span>size<span style="font-family: 宋体">域本身</span>(<span style="font-family: 宋体">子树所含节点个数</span>)<span style="font-family: 宋体">对于很多查询算法都特别有用，这样使得查询集合里面的譬如第</span>n<span style="font-family: 宋体">小的元素，以及一个元素在集合中的排名等操作都异常简单，并且时间复杂度都稳定在</span>O(log n)<span style="font-family: 宋体">。下面仅介绍下上表提到的</span>select(t,k)<span style="font-family: 宋体">操作和</span>rank(t,v)<span style="font-family: 宋体">操作。</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">由于</span>SBT<span style="font-family: 宋体">的性质（结点</span>t<span style="font-family: 宋体">的关键字比其左子树中所有结点的关键字都大，比其左子树中所有的关键字都小），理解下面的算法非常容易。</span></p>
<p><strong><span style="font-size: 12pt">3</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">．</span></strong><strong><span style="font-size: 12pt">Select</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">操作</span></strong></p>
<p>Select(t,k)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>If</strong> k=s[left[t]]+1 <strong>then</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return key[t]</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>If</strong> k&lt;=s[left[t]] <strong>then</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return Select(left[t],k)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Else</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return Select(right[t],k-1-s[left[t]])</p>
<p><strong><span style="font-size: 12pt">4</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">．</span></strong><strong><span style="font-size: 12pt">Rank</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">操作</span></strong></p>
<p>Rank(t,v)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>If</strong> t=0 <strong>then</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return 1</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>If</strong> v&lt;=key[t] <strong>then</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return rank(left[t],v)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <strong>Else</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> return s[left[t]]+1+rank(right[t],v)</p>
<p><span style="font-family: 宋体">同样</span>,<span style="font-family: 宋体">求前驱结点的操作</span>Pred<span style="font-family: 宋体">和后继结点的操作都很容易通过</span>size<span style="font-family: 宋体">域来实现。</span></p>
<p><strong>&nbsp;<wbr></strong></p>
<p><strong><span style="font-size: 14pt; font-family: 宋体">五．相关证明分析</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">显然</span>Maintain<span style="font-family: 宋体">操作是一个递归过程，可能你会怀疑它是否会结束。下面我们可以证明</span>Maintain<span style="font-family: 宋体">操作的平摊时间复杂度为</span>O(1)<span style="font-family: 宋体">。</span></p>
<p><strong><span style="font-size: 12pt">1</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">．关于树的高度的分析</span></strong></p>
<p><span style="font-family: 宋体">设</span>f[h]<span style="font-family: 宋体">表示高度为</span>h<span style="font-family: 宋体">的</span>SBT<span style="font-family: 宋体">中结点数目的最小值，则有</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> (h=0)</p>
<p style="margin-left: 63pt; text-indent: 42pt">f[h]=&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> (h=1)</p>
<p style="margin-left: 63pt; text-indent: 42pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> f[h-1]+f[h-2]+1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> (h&gt;1)</p>
<p>a<span style="font-family: 宋体">．证明：</span></p>
<p style="margin-left: 36pt; text-indent: -36pt">（1）<span style="font: 7pt 'Times new roman'; font-size-adjust: none; font-stretch: normal">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span> <span style="font-family: 宋体">很明显</span>f[0]=1,f[1]=2<span style="font-family: 宋体">。</span></p>
<p style="margin-left: 36pt; text-indent: -36pt">（2）<span style="font: 7pt 'Times new roman'; font-size-adjust: none; font-stretch: normal">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span> <span style="font-family: 宋体">首先，对于任意</span>h&gt;1,<span style="font-family: 宋体">我们假设</span>t<span style="font-family: 宋体">是一颗高度为</span>h<span style="font-family: 宋体">的</span>SBT<span style="font-family: 宋体">的根结点，则这颗</span>SBT<span style="font-family: 宋体">包含一颗高度为</span>h-1<span style="font-family: 宋体">的子树。不妨假设</span>t<span style="font-family: 宋体">的左子树的高度为</span>h-1<span style="font-family: 宋体">，根据</span>f[h]<span style="font-family: 宋体">的定义，有</span></p>
<p style="margin-left: 36pt">s[left[t] ]<span style="font-family: 宋体">&#8805;f[h-1]，同样的，左子树中有一颗高度为h-2的子树，换句话说，左子树中含有一颗结点数至少为f[h-2]的子树。由SBT的性质(b)，可知s[right[t]] &#8805;f[h-2]。因此我们有s[t]=s[left[t]]+s[right[t]]+1&#8805;f[h-1]+f[h-2]+1。</span></p>
<p style="margin-left: 36pt"><span style="font-family: 宋体">另外一方面，我们可以构造一颗高度为</span>h<span style="font-family: 宋体">，并且结点数正好为</span>f[h]<span style="font-family: 宋体">的</span>SBT,<span style="font-family: 宋体">称这样的</span>SBT<span style="font-family: 宋体">为</span>tree[t]<span style="font-family: 宋体">。可以这样来构造</span>tree[h]<span style="font-family: 宋体">：</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">含有一个结点的</span>SBT&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>(h=0)</p>
<p style="margin-left: 84pt; text-indent: 10.5pt">tree[h]=&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">含有</span>2<span style="font-family: 宋体">个结点的任意</span>SBT&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>(h=1)</p>
<p style="margin-left: 63pt; text-indent: 42pt">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> <span style="font-family: 宋体">左子树为</span>tree[h-1],<span style="font-family: 宋体">右子树为</span>tree[h-2]<span style="font-family: 宋体">的</span>SBT&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> (h&gt;1)</p>
<p style="margin-left: 36pt"><span style="font-family: 宋体">由</span>f[h]<span style="font-family: 宋体">的定义可知</span>f[h] <span style="font-family: 宋体">&#8804;</span>f[h-1]+f[h-2]+1(h&gt;1)<span style="font-family: 宋体">。因此</span>f[h]<span style="font-family: 宋体">的上下界都为</span>f[h-1]+f[h-2]+1,<span style="font-family: 宋体">因此有</span>f[h]=f[h-1]+f[h-2]+1<span style="font-family: 宋体">。</span></p>
<p>b<span style="font-family: 宋体">．最坏情况下的高度</span></p>
<p><span style="font-family: 宋体">事实上</span>f[h]<span style="font-family: 宋体">是一个指数函数，通过</span>f[h]<span style="font-family: 宋体">的递推可以计算出通项公式。</span></p>
<p><span style="font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c7.jpg" border="0" /><br />
</span></p>
<p>&nbsp;<wbr></p>
<p><span style="font-family: 宋体">定理：</span></p>
<p><span style="font-family: 宋体">含有</span>n<span style="font-family: 宋体">个结点的</span>SBT<span style="font-family: 宋体">在最坏情况下的高度是满足</span>f[h] <span style="font-family: 宋体">&#8804;</span>n<span style="font-family: 宋体">的最大的</span>h<span style="font-family: 宋体">值。</span></p>
<p><span style="font-family: 宋体">假设</span>maxh<span style="font-family: 宋体">为含有</span>n<span style="font-family: 宋体">个结点的</span>SBT<span style="font-family: 宋体">的最坏情况下的高度。由上面的定理，有</span></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c8.jpg" border="0" />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p><span style="font-family: 宋体">于是很明显</span>SBT<span style="font-family: 宋体">的高度为</span>O(logn)<span style="font-family: 宋体">，是一颗高度平衡的</span>BST<span style="font-family: 宋体">！</span></p>
<p><strong><span style="font-size: 12pt">2</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">．对</span></strong><strong><span style="font-size: 12pt">Maintain</span></strong><strong><span style="font-size: 12pt; font-family: 宋体">操作的分析</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">通过前面的计算分析我们能够很容易分析出</span>Maintain<span style="font-family: 宋体">操作是非常高效的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">首先，有一个非常重要的值来评价一颗</span>BST<span style="font-family: 宋体">的好坏：所有结点的平均深度。它是通过所有结点的深度之和</span>SD<span style="font-family: 宋体">除以结点个数</span>n<span style="font-family: 宋体">计算出来的。一般来说，这个值越小，这颗</span>BST<span style="font-family: 宋体">就越好。由于对于一颗</span>BST<span style="font-family: 宋体">来说，结点数</span>n<span style="font-family: 宋体">是一个常数，因此我们期望</span>SD<span style="font-family: 宋体">值越小越好。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">现在我们集中来看</span>SBT<span style="font-family: 宋体">的</span>SD<span style="font-family: 宋体">值，它的重要性在于能够制约</span>Maintain<span style="font-family: 宋体">操作的执行时间。回顾先前提到的</span>BST<span style="font-family: 宋体">中的旋转操作，有个重要的性质就是：每次执行旋转操作后，</span>SD<span style="font-family: 宋体">值总是递减的！</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">由于</span>SBT<span style="font-family: 宋体">树的高度总是</span>O(log n)<span style="font-family: 宋体">，因此</span>SD<span style="font-family: 宋体">值也总是保持在</span>O<span style="font-family: 宋体">（</span>log n<span style="font-family: 宋体">）。并且</span>SD<span style="font-family: 宋体">仅在插入一个结点到</span>SBT<span style="font-family: 宋体">后才增加，因此</span>(T<span style="font-family: 宋体">是</span>Maintain<span style="font-family: 宋体">操作中执行旋转的次数</span>)</p>
<p style="text-indent: 21pt"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c9.jpg" border="0" /><br />
</p>
<p style="text-indent: 21pt; text-align: center" align="center">&nbsp;<wbr></p>
<p>Maintain<span style="font-family: 宋体">操作的次数等于</span>T<span style="font-family: 宋体">加上不需要旋转操作的</span>Maintain<span style="font-family: 宋体">操作的次数。由于后者为</span>O(nlogn)+O(T),<span style="font-family: 宋体">因此</span>Maintain<span style="font-family: 宋体">的平摊分析时间复杂度为：</span></p>
<p><span style="font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/woodfish1988/c10.jpg" border="0" /><br />
</span></p>
<p style="text-align: center" align="center">&nbsp;<wbr></p>
<p style="margin-left: 18pt; text-indent: -18pt"><strong><span style="font-size: 12pt; font-family: 宋体">对各个操作时间复杂度的分析</span></strong></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">现在我们知道了</span>SBT<span style="font-family: 宋体">的高度为</span>O(log n)<span style="font-family: 宋体">，并且</span>&nbsp;<wbr>Maintain<span style="font-family: 宋体">操作的平摊分析时间复杂度为</span>O(1)<span style="font-family: 宋体">，因此对于所有的常用操作，时间复杂度都稳定在</span>O(log n)<span style="font-family: 宋体">！</span></p>
<p><!-- --></span></p><img src ="http://www.blogjava.net/dongwq/aggbug/299996.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-28 01:07 <a href="http://www.blogjava.net/dongwq/archive/2009/10/28/299996.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>目前最快的数独求解程序 - 实现了Knuth的Dancing Links+Algorithm X算法 </title><link>http://www.blogjava.net/dongwq/archive/2009/10/26/299853.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 26 Oct 2009 15:11:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/26/299853.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299853.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/26/299853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299853.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299853.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 目前最快的数独求解程序 - 实现了Knuth的Dancing Links+Algorithm X算法 C++语言: 目前最快的数独求解程序 - 实现了Knuth的Dancing Links+Algorithm X算法//from: http://code.google.com/p/klsudoku/source/checkout//半瓶墨水修改于 2009 Sept 18//R...&nbsp;&nbsp;<a href='http://www.blogjava.net/dongwq/archive/2009/10/26/299853.html'>阅读全文</a><img src ="http://www.blogjava.net/dongwq/aggbug/299853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-26 23:11 <a href="http://www.blogjava.net/dongwq/archive/2009/10/26/299853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最大公约数和最小公倍数 </title><link>http://www.blogjava.net/dongwq/archive/2009/10/26/299852.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 26 Oct 2009 14:56:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/26/299852.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299852.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/26/299852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299852.html</trackback:ping><description><![CDATA[<h3>最大公约数和最小公倍数 </h3>
语言: <a href="http://fayaa.com/code/view/?lang=c">C</a>, 标签: 无&nbsp; 2008/07/22发布 5个月前更新 <a href="http://fayaa.com/code/view/206/updates/">更新记录</a> <br />
作者: <a href="http://fayaa.com/code/user/5/">半瓶墨水</a>, 点击5221次, <a href="http://fayaa.com/code/view/206/#comments">评论(0)</a>, <a href="http://fayaa.com/code/view/206/fav/">收藏者(<span id="fav_count">0</span>)</a>, , 打分:<span id="ratings">登录以后才能打分, 目前平均0.0分，总分0, 共有0个用户参与打分</span>
<div id="codee_html" sizset="46" sizcache="2">
<div style="background: #fdfdfd; color: black" sizset="46" sizcache="2"><u>C语言</u>: <a href="http://fayaa.com/code/view/206/">最大公约数和最小公倍数</a></div>
<div class="source" style="color: #000000; font-family: '[object]','Consolas','Lucida Console','Courier New'" jquery1256563122468="14"><span style="color: #008080"># 以下描述来自： http:</span><span style="color: #008800; font-style: italic">//baike.baidu.com/view/47637.htm</span><br />
<span style="color: #008080">#</span><br />
<span style="color: #008080"># 最大公约数（greatest common divisor，简写为gcd；</span><br />
<span style="color: #008080">#　指某几个整数共有公约数中的最大一个</span><br />
<span style="color: #008080">#　　例: 在2、4、6中，2就是2，4，6的最大公约数。</span><br />
<span style="color: #008080">#</span><br />
<span style="color: #008080"># 重要性质：</span><br />
<span style="color: #008080"># gcd(a,b)=gcd(b,a) （交换律）</span><br />
<span style="color: #008080"># gcd(-a,b)=gcd(a,b)</span><br />
<span style="color: #008080"># gcd(a,a)=|a|</span><br />
<span style="color: #008080"># gcd(a,0)=|a|</span><br />
<span style="color: #008080"># gcd(a,1)=1</span><br />
<span style="color: #008080"># gcd(a,b)=gcd(b, a mod b)</span><br />
<span style="color: #008080"># gcd(a,b)=gcd(b, a-b)</span><br />
<span style="color: #008080"># 如果有附加的一个自然数m,</span><br />
<span style="color: #008080"># 则: gcd(ma,mb)=m * gcd(a,b) (分配率)</span><br />
<span style="color: #008080"># gcd(a+mb ,b)=gcd(a,b)</span><br />
<span style="color: #008080"># 如果m是a和b的最大公约数，</span><br />
<span style="color: #008080"># 则： gcd(a/m ,b/m)=gcd(a,b)/m</span><br />
<span style="color: #008080"># 在乘法函数中有：</span><br />
<span style="color: #008080"># gcd(ab,m)=gcd(a,m) * gcd(b,m) </span><br />
<span style="color: #008080"># 两个整数的最大公约数主要有两种寻找方法：</span><br />
<span style="color: #008080"># * 两数各分解质因子，然后取出同样有的项乘起来</span><br />
<span style="color: #008080"># * 辗转相除法（扩展版）</span><br />
<span style="color: #008080"># 和最小公倍数（lcm）的关系：</span><br />
<span style="color: #008080"># gcd(a, b) * lcm(a, b) = ab</span><br />
<span style="color: #008080"># a与b有最大公约数，但不一定有最小公倍数。</span><br />
<span style="color: #008080"># 两个整数的最大公因子可用于计算两数的最小公倍数，或分数化简成最简分数。</span><br />
<span style="color: #008080"># 两个整数的最大公因子和最小公倍数中存在分配律：</span><br />
<span style="color: #008080"># * gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c))</span><br />
<span style="color: #008080"># * lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c))</span><br />
<span style="color: #008080"># 在坐标里，将点(0, 0)和(a, b)连起来，通过整数坐标的点的数目（除了(0, 0)一点之外）就是gcd(a, b)。</span><br />
<span style="color: #008080">#</span><br />
<span style="color: #008080">#</span><br />
<span style="color: #008080"># 以下代码来自： http:</span><span style="color: #008800; font-style: italic">//bbs.bccn.net/thread-224663-1-1.html</span><br />
<span style="color: #008080"># </span><br />
<span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">GCD</span>(<span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">a</span><span style="color: #000000">,</span> <span style="font-weight: bold; color: #000080">int</span> b)<br />
<span style="color: #000000">{</span><br />
&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">if</span>(b <span style="color: #000000">==</span> <span style="color: #0000ff">0</span>) <span style="font-weight: bold; color: #000080">return</span> <span style="color: #000000">a</span>;<br />
&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">else</span> <span style="font-weight: bold; color: #000080">return</span> <span style="color: #000000">GCD</span>(b<span style="color: #000000">,</span> <span style="color: #000000">a</span> <span style="color: #000000">%</span> b);<br />
<span style="color: #000000">}</span><br />
<br />
<span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">LCM</span>(<span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">a</span><span style="color: #000000">,</span> <span style="font-weight: bold; color: #000080">int</span> b)<br />
<span style="color: #000000">{</span><br />
&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">return</span> <span style="color: #000000">a</span> <span style="color: #000000">*</span> b <span style="color: #000000">/</span> <span style="color: #000000">GCD</span>(<span style="color: #000000">a</span><span style="color: #000000">,</span>b);<br />
<span style="color: #000000">}</span><br />
<br />
<span style="color: #008800; font-style: italic">/*以下代码来自：http://en.wikipedia.org/wiki/Binary_GCD_algorithm */</span><br />
<span style="font-weight: bold; color: #000080">unsigned</span> <span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">gcd</span>(<span style="font-weight: bold; color: #000080">unsigned</span> <span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">u</span><span style="color: #000000">,</span> <span style="font-weight: bold; color: #000080">unsigned</span> <span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">v</span>)<br />
<span style="color: #000000">{</span><br />
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">shift</span>;<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: #008800; font-style: italic">/* GCD(0,x) := x */</span><br />
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">if</span> (<span style="color: #000000">u</span> <span style="color: #000000">==</span> <span style="color: #0000ff">0</span> || <span style="color: #000000">v</span> <span style="color: #000000">==</span> <span style="color: #0000ff">0</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">return</span> <span style="color: #000000">u</span> | <span style="color: #000000">v</span>;<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: #008800; font-style: italic">/* Let shift := lg K, where K is the greatest power of 2</span><br />
<span style="color: #008800; font-style: italic">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dividing both u and v. */</span><br />
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">for</span> (<span style="color: #000000">shift</span> <span style="color: #000000">=</span> <span style="color: #0000ff">0</span>; ((<span style="color: #000000">u</span> | <span style="color: #000000">v</span>) <span style="color: #000000">&amp;</span> <span style="color: #0000ff">1</span>) <span style="color: #000000">==</span> <span style="color: #0000ff">0</span>; <span style="color: #000000">++</span><span style="color: #000000">shift</span>) <span style="color: #000000">{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">u</span> <span style="color: #000000">&gt;&gt;=</span> <span style="color: #0000ff">1</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">v</span> <span style="color: #000000">&gt;&gt;=</span> <span style="color: #0000ff">1</span>;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #000000">}</span><br />
<br />
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">while</span> ((<span style="color: #000000">u</span> <span style="color: #000000">&amp;</span> <span style="color: #0000ff">1</span>) <span style="color: #000000">==</span> <span style="color: #0000ff">0</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">u</span> <span style="color: #000000">&gt;&gt;=</span> <span style="color: #0000ff">1</span>;<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="color: #008800; font-style: italic">/* From here on, u is always odd. */</span><br />
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">do</span> <span style="color: #000000">{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">while</span> ((<span style="color: #000000">v</span> <span style="color: #000000">&amp;</span> <span style="color: #0000ff">1</span>) <span style="color: #000000">==</span> <span style="color: #0000ff">0</span>)&nbsp; <span style="color: #008800; font-style: italic">/* Loop X */</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">v</span> <span style="color: #000000">&gt;&gt;=</span> <span style="color: #0000ff">1</span>;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #008800; font-style: italic">/* Now u and v are both odd, so diff(u, v) is even.</span><br />
<span style="color: #008800; font-style: italic">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Let u = min(u, v), v = diff(u, v)/2. */</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">if</span> (<span style="color: #000000">u</span> <span style="color: #000000">&lt;</span> <span style="color: #000000">v</span>) <span style="color: #000000">{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">v</span> <span style="color: #000000">-=</span> <span style="color: #000000">u</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">}</span> <span style="font-weight: bold; color: #000080">else</span> <span style="color: #000000">{</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">unsigned</span> <span style="font-weight: bold; color: #000080">int</span> <span style="color: #000000">diff</span> <span style="color: #000000">=</span> <span style="color: #000000">u</span> <span style="color: #000000">-</span> <span style="color: #000000">v</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">u</span> <span style="color: #000000">=</span> <span style="color: #000000">v</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">v</span> <span style="color: #000000">=</span> <span style="color: #000000">diff</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">}</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000">v</span> <span style="color: #000000">&gt;&gt;=</span> <span style="color: #0000ff">1</span>;<br />
&nbsp;&nbsp;&nbsp; <span style="color: #000000">}</span> <span style="font-weight: bold; color: #000080">while</span> (<span style="color: #000000">v</span> <span style="color: #000000">!=</span> <span style="color: #0000ff">0</span>);<br />
<br />
&nbsp;&nbsp;&nbsp; <span style="font-weight: bold; color: #000080">return</span> <span style="color: #000000">u</span> <span style="color: #000000">&lt;&lt;</span> <span style="color: #000000">shift</span>;<br />
<span style="color: #000000">}</span><br />
</div>
</div><img src ="http://www.blogjava.net/dongwq/aggbug/299852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-26 22:56 <a href="http://www.blogjava.net/dongwq/archive/2009/10/26/299852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sorting</title><link>http://www.blogjava.net/dongwq/archive/2009/10/26/299753.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 26 Oct 2009 03:53:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/26/299753.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299753.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/26/299753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299753.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299753.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;1package&nbsp;dwq.algo.sort;&nbsp;&nbsp;2&nbsp;&nbsp;3import&nbsp;java.util.Arrays;&nbsp;&nbsp;4&nbsp;&nbsp;5public&nbsp;class&nbsp;Sorting&nbsp;&nbsp;6{&nbsp;&nbsp;7...&nbsp;&nbsp;<a href='http://www.blogjava.net/dongwq/archive/2009/10/26/299753.html'>阅读全文</a><img src ="http://www.blogjava.net/dongwq/aggbug/299753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-26 11:53 <a href="http://www.blogjava.net/dongwq/archive/2009/10/26/299753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LongestIncrementSubarray</title><link>http://www.blogjava.net/dongwq/archive/2009/10/26/299750.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Mon, 26 Oct 2009 03:39:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/26/299750.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299750.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/26/299750.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299750.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299750.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: package&nbsp;com.dwq.algo;import&nbsp;java.util.ArrayList;public&nbsp;class&nbsp;LongestIncrementSubarray{&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;arg...&nbsp;&nbsp;<a href='http://www.blogjava.net/dongwq/archive/2009/10/26/299750.html'>阅读全文</a><img src ="http://www.blogjava.net/dongwq/aggbug/299750.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-26 11:39 <a href="http://www.blogjava.net/dongwq/archive/2009/10/26/299750.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>算法资源链接</title><link>http://www.blogjava.net/dongwq/archive/2009/10/26/299711.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Sun, 25 Oct 2009 17:09:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/26/299711.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299711.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/26/299711.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299711.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299711.html</trackback:ping><description><![CDATA[召集）你能想到的最奇妙的算法题是什么？<br />
http://www.matrix67.com/blog/archives/1850<br />
<br />
DLX<br />
http://sqybi.com/works/dlxcn/ <br />
<br />
<br />
<div style="display: inline"><strong id="t_4a443fd701000bko">OI最后的谢幕&#183;18岁新的开始<strong>http://blog.sina.com.cn/s/blog_4a443fd701000bko.html</strong></strong></div><img src ="http://www.blogjava.net/dongwq/aggbug/299711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-26 01:09 <a href="http://www.blogjava.net/dongwq/archive/2009/10/26/299711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>求数组中最长递增子序列</title><link>http://www.blogjava.net/dongwq/archive/2009/10/25/299653.html</link><dc:creator>小强摩羯座</dc:creator><author>小强摩羯座</author><pubDate>Sun, 25 Oct 2009 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/dongwq/archive/2009/10/25/299653.html</guid><wfw:comment>http://www.blogjava.net/dongwq/comments/299653.html</wfw:comment><comments>http://www.blogjava.net/dongwq/archive/2009/10/25/299653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dongwq/comments/commentRss/299653.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dongwq/services/trackbacks/299653.html</trackback:ping><description><![CDATA[<div>最长递增子序列的求法　LIS (转)</div>
<table style="table-layout: fixed; width: 100%">
    <tbody>
        <tr>
            <td>
            <div id="blog_text">
            <p>什么是最长递增子序列呢?<br />
            问题描述如下:<br />
            &nbsp;&nbsp; 设L=&lt;a1,a2,&#8230;,an&gt;是n个不同的实数的序列，L的递增子序列是这样一个子序列Lin=&lt;aK1,ak2,&#8230;,akm&gt;，其中k1&lt;k2&lt;&#8230;&lt;km且aK1&lt;ak2&lt;&#8230;&lt;akm。求最大的m值。<br />
            对于这个问题有以下几种解决思路:<br />
            &nbsp;&nbsp; 1、把a1,a2,...,an排序，假设得到a'1,a'2,...,a'n，然后求a的a'的最长公共子串，这样总的时间复杂度为o(nlg(n))+o(n^2)=o(n^2);<br />
            &nbsp;&nbsp; 2、动态规划的思路：<br />
            &nbsp;&nbsp;&nbsp; 另设一辅助数组b,定义b[n]表示以a[n]结尾的最长递增子序列的长度，则状态转移方程如下：b[k]=max(max(b[j]|a[j]&lt;a[k],j&lt;k)+1,1);<br />
            &nbsp;&nbsp;&nbsp; 这个状态转移方程解释如下：在a[k]前面找到满足a[j]&lt;a[k]的最大b[j],然后把a[k]接在它的后面，可得到a[k]的最长递增子序列的长度，或者a[k]前面没有比它小的a[j]，那么这时a[k]自成一序列，长度为1.最后整个数列的最长递增子序列即为max(b[k]&nbsp;&nbsp; | 0&lt;=k&lt;=n-1);<br />
            &nbsp;&nbsp;&nbsp; 实现代码如下：<br />
            &nbsp;&nbsp;&nbsp;&nbsp;</p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">#include &lt;iostream&gt;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">using namespace std;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">int main()</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">{</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i,j,n,a[100],b[100],max;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(cin&gt;&gt;n)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;n;i++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cin&gt;&gt;a[i];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b[0]=1;//</font>初始化，以<font face="Times New Roman">a[0]</font>结尾的最长递增子序列长度为<font face="Times New Roman">1</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=1;i&lt;n;i++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b[i]=1;//b[i]</font>最小值为<font face="Times New Roman">1</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=0;j&lt;i;j++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&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; if(a[i]&gt;a[j]&amp;&amp;b[j]+1&gt;b[i])</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&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; b[i]=b[j]+1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(max=i=0;i&lt;n;i++)//</font>求出整个数列的最长递增子序列的长度</p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(b[i]&gt;max)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&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; max=b[i];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;max&lt;&lt;endl;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">}</font></p>
            <p>&nbsp;&nbsp;&nbsp; 显然，这种方法的时间复杂度仍为o(n^2);<br />
            &nbsp;&nbsp; 3、对第二种思路的改进：<br />
            &nbsp;&nbsp;&nbsp; 第二种思路在状态转移时的复杂度为o(n),即在找a[k]前面满足a[j]&lt;a[k]的最大b[j]时采用的是顺序查找的方法，复杂度为o(n).<br />
            &nbsp;&nbsp;&nbsp; 设想如果能把顺序查找改为折半查找，则状态转移时的复杂度为o(lg(n)),这个问题的总的复杂度就可以降到nlg(n).<br />
            &nbsp;&nbsp;&nbsp; 另定义一数组c,c中元素满足c[b[k]]=a[k],解释一下，即当递增子序列的长度为b[k]时子序列的末尾元素为c[b[k]]=a[k].<br />
            &nbsp;&nbsp;&nbsp; 先给出这种思路的代码，然后再对其做出解释。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;</p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">#include &lt;iostream&gt;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">using namespace std;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">int find(int *a,int len,int n)//</font>若返回值为<font face="Times New Roman">x,</font>则<font face="Times New Roman">a[x]&gt;=n&gt;a[x-1]</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">{</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int left=0,right=len,mid=(left+right)/2;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(left&lt;=right)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(n&gt;a[mid]) left=mid+1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(n&lt;a[mid]) right=mid-1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else return mid;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mid=(left+right)/2;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return left;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">}</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">void fill(int *a,int n)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">{</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;=n;i++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[i]=1000;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">}</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">int main()</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">{</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int max,i,j,n,a[100],b[100],c[100];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(cin&gt;&gt;n)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill(c,n+1);</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;n;i++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cin&gt;&gt;a[i];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[0]=-1;//&nbsp;&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;1</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[1]=a[0];//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;2</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b[0]=1;//&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;3</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=1;i&lt;n;i++)//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;4</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j=find(c,n+1,a[i]);//&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;5</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[j]=a[i];// &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;6</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b[i]=j;//&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;7</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(max=i=0;i&lt;n;i++)//&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;8</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(b[i]&gt;max)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&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; max=b[i];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;max&lt;&lt;endl;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">}</font></p>
            <p>&nbsp;&nbsp;&nbsp; 对于这段程序，我们可以用算法导论上的loop invariants来帮助理解.<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">loop invariant</font>: 1、每次循环结束后c都是单调递增的。(这一性质决定了可以用二分查找）<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; 2、每次循环后，c[i]总是保存长度为i的递增子序列的最末的元素，若长度为i的递增子序</p>
            <p>&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; 列有多个，刚保存末尾元素最小的那个.（这一性质决定是第3条性质成立的前提）<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; 3、每次循环完后，b[i]总是保存以a[i]结尾的最长递增子序列。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">initialization:</font>&nbsp;&nbsp;&nbsp; 1、进入循环之前，c[0]=-1,c[1]=a[0],c的其他元素均为1000,c是单调递增的;<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; 2、进入循环之前，c[1]=a[0],保存了长度为1时的递增序列的最末的元素，且此时长度为1</p>
            <p>&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; 的递增了序列只有一个，c[1]也是最小的;<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; 3、进入循环之前，b[0]=1，此时以a[0]结尾的最长递增子序列的长度为1.<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">maintenance:</font>&nbsp;&nbsp; 1、若在第n次循环之前c是单调递增的，则第n次循环时，c的值只在第6行发生变化，而由</p>
            <p>&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; c进入循环前单调递增及find函数的性质可知（见find的注释),</p>
            <p>&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; 此时c[j+1]&gt;c[j]&gt;=a[i]&gt;c[j-1],所以把c[j]的值更新为a[i]后，c[j+1]&gt;c[j]&gt;c[j-1]的性质仍然成</p>
            <p>&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; 立，即c仍然是单调递增的；<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; 2、循环中，c的值只在第6行发生变化，由c[j]&gt;=a[i]可知，c[j]更新为a[i]后，c[j]的值只会变</p>
            <p>&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; 小不会变大，因为进入循环前c[j]的值是最小的，则循环中把c[j]更新为更小的a[i]，当</p>
            <p>&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; 然此时c[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;&nbsp; 3、循环中，b[i]的值在第7行发生了变化，因为有loop invariant的性质2，find函数返回值</p>
            <p>&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; 为j有：c[j-1]&lt;a[i]&lt;=c[j],这说明c[j-1]是小于a[i]的，且以c[j-1]结尾的递增子序列有最大的</p>
            <p>&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; 长度，即为j-1,把a[i]接在c[j-1]后可得到以a[i]结尾的最长递增子序列，长度为(j-1)+1=j;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">termination:</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 循环完后，i=n-1,b[0],b[1],...,b[n-1]的值均已求出，即以a[0],a[1],...,a[n-1]结尾的最长递</p>
            <p>&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; 增子序列的长度均已求出，再通过第8行的循环，即求出了整个数组的最长递增子序列。</p>
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 仔细分析上面的代码可以发现，每次循环结束后，假设已经求出c[1],c[2],c[3],...,c[len]的值，则此时最长递增子序列的长度为len,因此可以把上面的代码更加简化，即可以不需要数组b来辅助存储，第8行的循环也可以省略。<br />
            &nbsp;&nbsp;&nbsp;&nbsp;</p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">#include &lt;iostream&gt;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">using namespace std;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">int find(int *a,int len,int n)//</font>修改后的二分查找，若返回值为<font face="Times New Roman">x</font>，则<font face="Times New Roman">a[x]&gt;=n</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">{</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int left=0,right=len,mid=(left+right)/2;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(left&lt;=right)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(n&gt;a[mid]) left=mid+1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(n&lt;a[mid]) right=mid-1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else return mid;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mid=(left+right)/2;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return left;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">}</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">int main()</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">{</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int n,a[100],b[100],c[100],i,j,len;//</font>新开一变量<font face="Times New Roman">len,</font>用来储存每次循环结束后<font face="Times New Roman">c</font>中已经求出值的元素的最大下标</p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(cin&gt;&gt;n)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;n;i++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cin&gt;&gt;a[i];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b[0]=1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[0]=-1;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[1]=a[0];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len=1;//</font>此时只有<font face="Times New Roman">c[1]</font>求出来，最长递增子序列的长度为<font face="Times New Roman">1.</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=1;i&lt;n;i++)</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j=find(c,len,a[i]);</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[j]=a[i];</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(j&gt;len)//</font>要更新<font face="Times New Roman">len,</font>另外补充一点：由二分查找可知<font face="Times New Roman">j</font>只可能比<font face="Times New Roman">len</font>大<font face="Times New Roman">1</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&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; len=j;//</font>更新<font face="Times New Roman">len</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;len&lt;&lt;endl;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</font></p>
            <p style="margin: 0cm 0cm 0pt"><font face="Times New Roman">}</font></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<div class="tit">最长递增部分序列 Longest Ordered Subsequence Extention hoj10027 poj2533</div>
<div class="date">2007-08-21 20:19</div>
<table style="table-layout: fixed; width: 100%">
    <tbody>
        <tr>
            <td>
            <div class="cnt" id="blog_text">
            <p><font color="#3366ff">求最长递增部分序列是一个比较常见的动态规划题。在导弹拦截等题中都有用到。一般来说就是用经典的O(n^2)的动态规划算法。</font></p>
            <p><font color="#3366ff">算法如下：</font></p>
            <p><font color="#3366ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设A[i]表示序列中的第i个数，F[i]表示从1到i这一段中以i结尾的最长上升子序列的长度，初始时设F[i] = 0(i = 1, 2, ..., len(A))。则有动态规划方程：F[i] = max{1, F[j] + 1} (j = 1, 2, ..., i - 1, 且A[j] &lt; A[i])。</font></p>
            <p><font color="#3366ff">然而在hoj10027中n的值达到了50000。显而易见经典算法是会超时滴。所以只有另谋出路了。</font></p>
            <p><font color="#3366ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用一个变量len记录到目前为止所找出来的最长递增序列的长度。另外准备一个数组b[]，用这个数组表示长度为j的递增序列中最后一个元素的值。在这里长度为j的递增序列不止一个，我们所要保存是那个最小的。为什么呢？因为最后一个元素越小，那么这个递增序列在往后被延长的机会越大。初始化b[0] = -1;len = 0;从第一个元素a[1]开始&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[i]( 1 &lt;= i &lt;= n)。如果这个元素比len长的序列的最大值大。则把这个元素直接添加到b数组的后面。如果这个元素比b数组的第一个元素还要小则把这个元素赋给b数组的第一个值。否则进行二分查找。当在b数组里面找到一个数比a[i]小，并且他的后面的数大于或等于a[i]则跳出。将a[i]添加到这个数的后面。输出len就可以了。</font></p>
            <p><font color="#3366ff">代码如下：</font></p>
            <p><font color="#3366ff">#include &lt;stdio.h&gt;<br />
            #include &lt;string.h&gt;<br />
            int main()<br />
            {<br />
            int a[50001], b[50001];<br />
            int i, j, l, r, len, n, mid;<br />
            while (scanf("%d", &amp;n) != EOF)<br />
            {<br />
            &nbsp;&nbsp; for (i = 0; i &lt; n; i++)<br />
            &nbsp;&nbsp;&nbsp; scanf("%d", &amp;a[i]);<br />
            &nbsp;&nbsp; len = 0;<br />
            &nbsp;&nbsp; memset(b, 0, sizeof(int) * 50001);<br />
            &nbsp;&nbsp; b[0] = -1;<br />
            &nbsp;&nbsp; for (i = 0; i &lt; n; i++)<br />
            &nbsp;&nbsp; {<br />
            &nbsp;&nbsp;&nbsp; if (a[i] &gt; b[len])<br />
            &nbsp;&nbsp;&nbsp;&nbsp; b[++len] = a[i];<br />
            &nbsp;&nbsp;&nbsp; else if (a[i] &lt; b[1] )<br />
            &nbsp;&nbsp;&nbsp;&nbsp; b[1] = a[i]; <br />
            &nbsp;&nbsp;&nbsp; else<br />
            &nbsp;&nbsp;&nbsp; {<br />
            &nbsp;&nbsp;&nbsp;&nbsp; l = 1; r = len;<br />
            &nbsp;&nbsp;&nbsp;&nbsp; while (l &lt;= r)<br />
            &nbsp;&nbsp;&nbsp;&nbsp; {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mid = (l + r)&gt;&gt;1;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (a[i] &gt; b[mid] &amp;&amp; a[i] &lt;= b[mid + 1])<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j = mid;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (b[mid] &gt; a[i])<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r = mid - 1;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j = mid;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l = mid + 1;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp; b[j + 1] = a[i];<br />
            &nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp; }<br />
            &nbsp;&nbsp; printf("%d\n", len);<br />
            }<br />
            return 0;<br />
            </font></p>
            </div>
            </td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/dongwq/aggbug/299653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dongwq/" target="_blank">小强摩羯座</a> 2009-10-25 11:27 <a href="http://www.blogjava.net/dongwq/archive/2009/10/25/299653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>