﻿<?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>C++博客-mysileng-随笔分类-数据结构与算法</title><link>http://www.cppblog.com/mysileng/category/19943.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 16 Oct 2013 17:18:30 GMT</lastBuildDate><pubDate>Wed, 16 Oct 2013 17:18:30 GMT</pubDate><ttl>60</ttl><item><title>Dijkstra算法（单源最短路径）</title><link>http://www.cppblog.com/mysileng/archive/2013/10/16/203776.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Wed, 16 Oct 2013 12:31:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/10/16/203776.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/203776.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/10/16/203776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/203776.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/203776.html</trackback:ping><description><![CDATA[<p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">&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;Dijkstra算法（单源最短路径）</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单源最短路径问题，即在图中求出给定顶点到其它任一顶点的最短路径。在弄清楚如何求算单源最短路径问题之前，必须弄清楚最短路径的最优子结构性质。</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">一.最短路径的最优子结构性质</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">&nbsp;&nbsp; 该性质描述为：如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径，k和s是这条路径上的一个中间顶点，那么P(k,s)必定是从k到s的最短路径。下面证明该性质的正确性。</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">&nbsp;&nbsp; 假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径，则有P(i,j)=P(i,k)+P(k,s)+P(s,j)。而P(k,s)不是从k到s的最短距离，那么必定存在另一条从k到s的最短路径P'(k,s)，那么P'(i,j)=P(i,k)+P'(k,s)+P(s,j)&lt;P(i,j)。则与P(i,j)是从i到j的最短路径相矛盾。因此该性质得证。</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">二.Dijkstra算法</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">&nbsp;&nbsp; 由上述性质可知，如果存在一条从i到j的最短路径(Vi.....Vk,Vj)，Vk是Vj前面的一顶点。那么(Vi...Vk)也必定是从i到k的最短路径。为了求出最短路径，Dijkstra就提出了以最短路径长度递增，逐次生成最短路径的算法。譬如对于源顶点V0，首先选择其直接相邻的顶点中长度最短的顶点Vi，那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+matrix[i][j]}。根据这种思路，</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">假设存在G=&lt;V,E&gt;，源顶点为V0，U={V0},dist[i]记录V0到i的最短距离，path[i]记录从V0到i路径上的i前面的一个顶点。</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">1.从V-U中选择使dist[i]值最小的顶点i，将i加入到U中；</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">2.更新与i直接相邻顶点的dist值。(dist[j]=min{dist[j],dist[i]+matrix[i][j]})</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">3.知道U=V，停止。</p><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;">代码实现:<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/*</span><span style="color: #008000; ">Dijkstra求单源最短路径&nbsp;2010.8.26</span><span style="color: #008000; ">*/</span><br />&nbsp;<br />#include&nbsp;&lt;iostream&gt;<br />#include&lt;stack&gt;<br /><span style="color: #0000FF; ">#define</span>&nbsp;M&nbsp;100<br /><span style="color: #0000FF; ">#define</span>&nbsp;N&nbsp;100<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><br />typedef&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;node<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;matrix[N][M];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">邻接矩阵&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">顶点数&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;e;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">边数&nbsp;</span><span style="color: #008000; "><br /></span>}MGraph;&nbsp;<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;DijkstraPath(MGraph&nbsp;g,<span style="color: #0000FF; ">int</span>&nbsp;*dist,<span style="color: #0000FF; ">int</span>&nbsp;*path,<span style="color: #0000FF; ">int</span>&nbsp;v0)&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">v0表示源顶点&nbsp;</span><span style="color: #008000; "><br /></span>{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i,j,k;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;*visited=(<span style="color: #0000FF; ">bool</span>&nbsp;*)malloc(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">bool</span>)*g.n);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i=0;i&lt;g.n;i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">初始化&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(g.matrix[v0][i]&gt;0&amp;&amp;i!=v0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dist[i]=g.matrix[v0][i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[i]=v0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">path记录最短路径上从v0到i的前一个顶点&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dist[i]=INT_MAX;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">若i不与v0直接相邻，则权值置为无穷大&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[i]=-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visited[i]=<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[v0]=v0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dist[v0]=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;visited[v0]=<span style="color: #0000FF; ">true</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i=1;i&lt;g.n;i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">循环扩展n-1次&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;min=INT_MAX;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;u;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(j=0;j&lt;g.n;j++)&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">寻找未被扩展的权值最小的顶点&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(visited[j]==<span style="color: #0000FF; ">false</span>&amp;&amp;dist[j]&lt;min)<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;min=dist[j];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u=j;&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;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visited[u]=<span style="color: #0000FF; ">true</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(k=0;k&lt;g.n;k++)&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">更新dist数组的值和路径的值&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(visited[k]==<span style="color: #0000FF; ">false</span>&amp;&amp;g.matrix[u][k]&gt;0&amp;&amp;min+g.matrix[u][k]&lt;dist[k])<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;dist[k]=min+g.matrix[u][k];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path[k]=u;&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;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;showPath(<span style="color: #0000FF; ">int</span>&nbsp;*path,<span style="color: #0000FF; ">int</span>&nbsp;v,<span style="color: #0000FF; ">int</span>&nbsp;v0)&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">打印最短路径上的各个顶点&nbsp;</span><span style="color: #008000; "><br /></span>{<br />&nbsp;&nbsp;&nbsp;&nbsp;stack&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;s;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;u=v;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(v!=v0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.push(v);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v=path[v];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;s.push(v);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(!s.empty())<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;s.top()&lt;&lt;"&nbsp;";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.pop();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}&nbsp;<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*argv[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n,e;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">表示输入的顶点数和边数&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(cin&gt;&gt;n&gt;&gt;e&amp;&amp;e!=0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i,j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;s,t,w;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">表示存在一条边s-&gt;t,权值为w</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MGraph&nbsp;g;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;v0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*dist=(<span style="color: #0000FF; ">int</span>&nbsp;*)malloc(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">int</span>)*n);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*path=(<span style="color: #0000FF; ">int</span>&nbsp;*)malloc(<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">int</span>)*n);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i=0;i&lt;N;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(j=0;j&lt;M;j++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.matrix[i][j]=0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.n=n;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.e=e;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i=0;i&lt;e;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cin&gt;&gt;s&gt;&gt;t&gt;&gt;w;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.matrix[s][t]=w;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cin&gt;&gt;v0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">输入源顶点&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DijkstraPath(g,dist,path,v0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i=0;i&lt;n;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(i!=v0)<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;showPath(path,i,v0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;dist[i]&lt;&lt;endl;<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 style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div><p style="font-size: 13px; line-height: 23px; color: #0c0b0b; background-color: #fffdfd; font-family: 'Courier New', 微软雅黑, 宋体; margin-top: 10px !important; margin-bottom: 10px !important;"><br /><br /><br /></p><img src ="http://www.cppblog.com/mysileng/aggbug/203776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-10-16 20:31 <a href="http://www.cppblog.com/mysileng/archive/2013/10/16/203776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>逆序数及其求法</title><link>http://www.cppblog.com/mysileng/archive/2013/09/20/203315.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Fri, 20 Sep 2013 09:23:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/09/20/203315.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/203315.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/09/20/203315.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/203315.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/203315.html</trackback:ping><description><![CDATA[<p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">1. 逆序数</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">所谓逆序数，就是指一个序列S[i]，统计处于序列的每个数的比这个数大并且排在它前面的数的数目，然后对于所有数，把这个数目加起来求和就是了。<br />比如 4 3 1 2<br />4第一个，所以数目为0<br />3的前面是4，大于3的数目为1<br />1的前面是4 3 ，大于1的数目为2<br />2的前面是4 3 1，大于2的数目为2<br />所以逆序数为1+2+2 = 5</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">求逆序数的两种方法<br />常规方法是按照逆序数的规则做，结果复杂度是O(n*n)，一般来说，有两种快速的求逆序数的方法<br />分别是归并排序和树状数组法</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;"><br />2. 归并排序&nbsp;<br />归并排序是源于分而治之思想，详细的过程可以查阅其他资料，总体思想是划分一半，各自排好序后将两个有序序列合并起来。</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">如何修改归并排序求逆序数?<br />首先我们假设两个有序序列 a[i]和b[i]，当合并时：<br />由于a[i]已是有序，所以对于a[i]的各个元素来说，排在它前面且比它大的数目都是0<br />当b[i]中含有比a[i]小的元素时，我们必然将b[i]元素插到前面，那么就是说，在b[i]原先位置到该插的位置中，所有数都比b[i]大且排在它前面<br />所以这是b[i]的数目为新插入位置newPos - 原来位置oldPos</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">那么对于一半的序列又怎么做呢？我们知道，归并排序会继续向下递归，而递归完成返回后将是两组有序的序列，并且拿到局部的逆序数，<br />所以在Merge函数中添加这一计数操作即可<br /></p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">&nbsp;</p><span style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px; background-color: #ffffff;">代码示例如下：<br /></span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;L[M];<br /><span style="color: #0000FF; ">int</span>&nbsp;R[M];<br /><br /><span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;Max&nbsp;=&nbsp;1&nbsp;&lt;&lt;30;<br />__int64&nbsp;change&nbsp;=&nbsp;0;<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Merge(<span style="color: #0000FF; ">int</span>&nbsp;*data,<span style="color: #0000FF; ">int</span>&nbsp;left,<span style="color: #0000FF; ">int</span>&nbsp;divide,<span style="color: #0000FF; ">int</span>&nbsp;right)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;lengthL&nbsp;=&nbsp;divide&nbsp;-&nbsp;left;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;lengthR&nbsp;=&nbsp;right&nbsp;-&nbsp;divide;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;lengthL;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L[i]&nbsp;=&nbsp;data[left&nbsp;+&nbsp;i];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;lengthR;&nbsp;++i)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R[i]&nbsp;=&nbsp;data[divide&nbsp;+&nbsp;i];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;L[lengthL]&nbsp;=&nbsp;R[lengthR]&nbsp;=&nbsp;Max;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;k&nbsp;=&nbsp;left;&nbsp;k&nbsp;&lt;&nbsp;right;&nbsp;++k)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(L[i]&nbsp;&lt;=&nbsp;R[j])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data[k]&nbsp;=&nbsp;L[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change&nbsp;+=&nbsp;divide&nbsp;-&nbsp;i&nbsp;-&nbsp;left&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data[k]&nbsp;=&nbsp;R[j];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;MergeSort(<span style="color: #0000FF; ">int</span>&nbsp;*data,<span style="color: #0000FF; ">int</span>&nbsp;left,<span style="color: #0000FF; ">int</span>&nbsp;right)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(left&nbsp;&lt;&nbsp;right&nbsp;-1)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;divide&nbsp;=&nbsp;(left&nbsp;+&nbsp;right)/2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MergeSort(data,left,divide);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MergeSort(data,divide,right);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Merge(data,left,divide,right);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><span style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px; background-color: #ffffff;"><br /></span><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">3. 树状数组<br />求逆序数的另外一种方法是使用树状数组<br />对于小数据，可以直接插入树状数组，对于大数据，则需要离散化，所谓离散化，就是将<br />100 200 300 400 500 ---&gt; 1 2 3 4 5</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">这里主要利用树状数组解决计数问题。</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">首先按顺序把序列a[i]每个数插入到树状数组中，插入的内容是1，表示放了一个数到树状数组中。<br />然后使用sum操作获取当前比a[i]小的数，那么当前i - sum则表示当前比a[i]大的数，如此反复直到所有数都统计完，<br />比如<br />4 3 1 2&nbsp;<br />i = 1 : 插入 4 : update(4,1)，sum(4)返回1，那么当前比4大的为 i - 1 = 0;<br />i = 2 : 插入 3 : update(3,1)，sum(3)返回1，那么当前比3大的为 i - 1 = 1;<br />i = 3 : 插入 1 : update(1,1)，sum(1)返回1，那么当前比1大的为 i - 1 = 2;<br />i = 4 : 插入 2 : update(2,1)，sum(2)返回2，那么当前比2大的为 i - 2 = 2;</p><p style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px;">过程很明了，所以逆序数为1+2+2=5<br /><br />代码示例如下：</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">//</span><span style="color: #008000; ">树状数组</span><span style="color: #008000; "><br /></span>__int64&nbsp;sums[1005];<br /><span style="color: #0000FF; ">int</span>&nbsp;len;<br /><br />inline&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;lowbit(<span style="color: #0000FF; ">int</span>&nbsp;t)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;t&nbsp;&amp;&nbsp;(t^(t-1));&nbsp;<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;update(<span style="color: #0000FF; ">int</span>&nbsp;_x,<span style="color: #0000FF; ">int</span>&nbsp;_value)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(_x&nbsp;&lt;=&nbsp;len)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sums[_x]&nbsp;+=&nbsp;_value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_x&nbsp;+=&nbsp;lowbit(_x);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br />__int64&nbsp;sum(<span style="color: #0000FF; ">int</span>&nbsp;_end)<span style="color: #008000; ">//</span><span style="color: #008000; ">get&nbsp;sum[1_end]</span><span style="color: #008000; "><br /></span>{<br />&nbsp;&nbsp;&nbsp;&nbsp;__int64&nbsp;ret&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(_end&nbsp;&gt;&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;+=&nbsp;sums[_end];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_end&nbsp;-=&nbsp;lowbit(_end);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;ret;<br />}<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">求逆序数</span><span style="color: #008000; "><br /></span><br />__int64&nbsp;ret&nbsp;=&nbsp;0;<br /><span style="color: #0000FF; ">for</span>&nbsp;(__int64&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;k;&nbsp;++i)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;update(a[i],1);<br />&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;+=&nbsp;(i+1)&nbsp;-&nbsp;sum(a[i]);<br />}</div><span style="color: #7b7d62; font-family: verdana, Arial, helvetica, sans-seriff; font-size: 12px; line-height: 17.600000381469727px; background-color: #ffffff;"><br /><br /><br /><br /><br /></span><img src ="http://www.cppblog.com/mysileng/aggbug/203315.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-09-20 17:23 <a href="http://www.cppblog.com/mysileng/archive/2013/09/20/203315.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>m进制转换为n进制-任意进制转换算法</title><link>http://www.cppblog.com/mysileng/archive/2013/06/08/200879.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Sat, 08 Jun 2013 08:16:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/08/200879.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/200879.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/08/200879.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/200879.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/200879.html</trackback:ping><description><![CDATA[<p>转自:<font style="background-color: #cce8cf" color="#000000" face="Verdana">http://www.cnblogs.com/pkuoliver/archive/2010/10/27/Convert-m-number-to-n-number.html</font><br /><br />园子里有很多深藏不漏的高手，在这里聊这种基本问题是有点小儿科。不过本人只是想分享下自己的新的，代码，算法有不足之处，还请大家指正，共同进步。</p>
<p>&nbsp;</p>
<p>这种题也是一道经典的面试题，主要考察进制转换细想，Coding质量等。</p>
<p>当我们把十进制转成二进制的时候，我们通过辗转相除，取余，逆置余数序列的过程得到新的进制的数。因此我们可以借助这种思想把M进制转成N进制的数。</p>
<p>如下是C的详细的实现方法</p>
<p>&nbsp;</p>
<div class="cnblogs_Highlighter">
<div>
<div id="highlighter_914821" class="syntaxhighlighter  cpp ie ">
<div class="toolbar"><span><a class="toolbar_item command_help help" href="http://www.cnblogs.com/pkuoliver/archive/2010/10/27/Convert-m-number-to-n-number.html#">?</a></span></div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
<div class="line number13 index12 alt2">13</div>
<div class="line number14 index13 alt1">14</div>
<div class="line number15 index14 alt2">15</div>
<div class="line number16 index15 alt1">16</div>
<div class="line number17 index16 alt2">17</div>
<div class="line number18 index17 alt1">18</div>
<div class="line number19 index18 alt2">19</div>
<div class="line number20 index19 alt1">20</div>
<div class="line number21 index20 alt2">21</div>
<div class="line number22 index21 alt1">22</div>
<div class="line number23 index22 alt2">23</div></td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="cpp keyword bold">void</code> <code class="cpp plain">m2n(</code><code class="cpp color1 bold">int</code> <code class="cpp plain">m, </code><code class="cpp color1 bold">char</code><code class="cpp plain">* mNum, </code><code class="cpp color1 bold">int</code> <code class="cpp plain">n, </code><code class="cpp color1 bold">char</code><code class="cpp plain">* nNum)&nbsp; </code></div>
<div class="line number2 index1 alt1"><code class="cpp plain">{ </code></div>
<div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">int</code> <code class="cpp plain">i = 0; </code></div>
<div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp color1 bold">char</code> <code class="cpp plain">c, *p = nNum; </code></div>
<div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;</code>&nbsp;</div>
<div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">//这是一个考察地方，是否能用最少乘法次数。 </code></div>
<div class="line number7 index6 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">while</code> <code class="cpp plain">(*mNum != </code><code class="cpp string">'\0'</code><code class="cpp plain">) </code></div>
<div class="line number8 index7 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">i = i*m + *mNum++ - </code><code class="cpp string">'0'</code><code class="cpp plain">; </code></div>
<div class="line number9 index8 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code>&nbsp;</div>
<div class="line number10 index9 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">//辗转取余 </code></div>
<div class="line number11 index10 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">while</code> <code class="cpp plain">(i) { </code></div>
<div class="line number12 index11 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">*p++ = i % n + </code><code class="cpp string">'0'</code><code class="cpp plain">; </code></div>
<div class="line number13 index12 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">i /= n; </code></div>
<div class="line number14 index13 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">} </code></div>
<div class="line number15 index14 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">*p-- = </code><code class="cpp string">'\0'</code><code class="cpp plain">; </code></div>
<div class="line number16 index15 alt1"><code class="cpp spaces">&nbsp;</code>&nbsp;</div>
<div class="line number17 index16 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp comments">//逆置余数序列 </code></div>
<div class="line number18 index17 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">while</code> <code class="cpp plain">(p &gt; nNum) { </code></div>
<div class="line number19 index18 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">c = *p; </code></div>
<div class="line number20 index19 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">*p-- = *nNum; </code></div>
<div class="line number21 index20 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">*nNum++ = c; </code></div>
<div class="line number22 index21 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">} </code></div>
<div class="line number23 index22 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div></div>
<p>观察上面的代码，存在着众多的不足。例如，要对输入参数做检查，数值的大小收到int值最大值的限制等。不过好在一点，该算法的时间复杂度是O(n)的。</p>
<p>&nbsp;</p>
<p>我们霹雳无敌的赵大叔又提供了一种用Java实现的通用的进制转换方法，即使Windows的计算器也转不了的大数，这个算法也可以转。算和上面的算法相比，他的基本思想不变，还是辗转除，但是用了字符串做大数相除，很不错的创新点，赞一个。代码如下：</p>
<p>&nbsp;</p>
<div class="cnblogs_Highlighter">
<div>
<div id="highlighter_698984" class="syntaxhighlighter  java ie">
<div class="toolbar"><span><a class="toolbar_item command_help help" href="http://www.cnblogs.com/pkuoliver/archive/2010/10/27/Convert-m-number-to-n-number.html#">?</a></span></div>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
<div class="line number13 index12 alt2">13</div>
<div class="line number14 index13 alt1">14</div>
<div class="line number15 index14 alt2">15</div>
<div class="line number16 index15 alt1">16</div>
<div class="line number17 index16 alt2">17</div>
<div class="line number18 index17 alt1">18</div>
<div class="line number19 index18 alt2">19</div>
<div class="line number20 index19 alt1">20</div>
<div class="line number21 index20 alt2">21</div>
<div class="line number22 index21 alt1">22</div>
<div class="line number23 index22 alt2">23</div>
<div class="line number24 index23 alt1">24</div>
<div class="line number25 index24 alt2">25</div>
<div class="line number26 index25 alt1">26</div>
<div class="line number27 index26 alt2">27</div>
<div class="line number28 index27 alt1">28</div>
<div class="line number29 index28 alt2">29</div>
<div class="line number30 index29 alt1">30</div>
<div class="line number31 index30 alt2">31</div>
<div class="line number32 index31 alt1">32</div>
<div class="line number33 index32 alt2">33</div>
<div class="line number34 index33 alt1">34</div>
<div class="line number35 index34 alt2">35</div>
<div class="line number36 index35 alt1">36</div>
<div class="line number37 index36 alt2">37</div>
<div class="line number38 index37 alt1">38</div>
<div class="line number39 index38 alt2">39</div>
<div class="line number40 index39 alt1">40</div>
<div class="line number41 index40 alt2">41</div>
<div class="line number42 index41 alt1">42</div>
<div class="line number43 index42 alt2">43</div>
<div class="line number44 index43 alt1">44</div>
<div class="line number45 index44 alt2">45</div>
<div class="line number46 index45 alt1">46</div>
<div class="line number47 index46 alt2">47</div>
<div class="line number48 index47 alt1">48</div>
<div class="line number49 index48 alt2">49</div>
<div class="line number50 index49 alt1">50</div>
<div class="line number51 index50 alt2">51</div>
<div class="line number52 index51 alt1">52</div>
<div class="line number53 index52 alt2">53</div>
<div class="line number54 index53 alt1">54</div>
<div class="line number55 index54 alt2">55</div>
<div class="line number56 index55 alt1">56</div>
<div class="line number57 index56 alt2">57</div>
<div class="line number58 index57 alt1">58</div>
<div class="line number59 index58 alt2">59</div>
<div class="line number60 index59 alt1">60</div>
<div class="line number61 index60 alt2">61</div>
<div class="line number62 index61 alt1">62</div>
<div class="line number63 index62 alt2">63</div>
<div class="line number64 index63 alt1">64</div>
<div class="line number65 index64 alt2">65</div>
<div class="line number66 index65 alt1">66</div>
<div class="line number67 index66 alt2">67</div>
<div class="line number68 index67 alt1">68</div>
<div class="line number69 index68 alt2">69</div></td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="java keyword">package</code> <code class="java plain">test; </code></div>
<div class="line number2 index1 alt1"><code class="java spaces">&nbsp;</code>&nbsp;</div>
<div class="line number3 index2 alt2"><code class="java preprocessor">/** </code></div>
<div class="line number4 index3 alt1"><code class="java spaces">&nbsp;</code><code class="java preprocessor">* 功能：将一个数从M进制转换成N进制 </code></div>
<div class="line number5 index4 alt2"><code class="java spaces">&nbsp;</code><code class="java preprocessor">* MValue：M进制数的字符串表示方法 </code></div>
<div class="line number6 index5 alt1"><code class="java spaces">&nbsp;</code><code class="java preprocessor">* Shang：保存中间运算结果 </code></div>
<div class="line number7 index6 alt2"><code class="java spaces">&nbsp;</code><code class="java preprocessor">* M：M进制 </code></div>
<div class="line number8 index7 alt1"><code class="java spaces">&nbsp;</code><code class="java preprocessor">* N：N进制 </code></div>
<div class="line number9 index8 alt2"><code class="java spaces">&nbsp;</code><code class="java preprocessor">*/</code></div>
<div class="line number10 index9 alt1"><code class="java keyword">public</code> <code class="java keyword">class</code> <code class="java plain">M2N { </code></div>
<div class="line number11 index10 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java comments">// 在这里对输入赋值 </code></div>
<div class="line number12 index11 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java plain">String MValue = </code><code class="java string">"1231412423534674574757"</code><code class="java plain">; </code></div>
<div class="line number13 index12 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java plain">String Shang = </code><code class="java keyword">null</code><code class="java plain">; </code></div>
<div class="line number14 index13 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java keyword">int</code> <code class="java plain">M = </code><code class="java value">10</code><code class="java plain">; </code></div>
<div class="line number15 index14 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java keyword">int</code> <code class="java plain">N = </code><code class="java value">8</code><code class="java plain">; </code></div>
<div class="line number16 index15 alt1"><code class="java spaces">&nbsp;</code>&nbsp;</div>
<div class="line number17 index16 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java keyword">void</code> <code class="java plain">main(String[] args) { </code></div>
<div class="line number18 index17 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">String nValue = </code><code class="java string">""</code><code class="java plain">; </code></div>
<div class="line number19 index18 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">Shang = MValue; </code></div>
<div class="line number20 index19 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">while</code><code class="java plain">(Shang.length() &gt; </code><code class="java value">0</code><code class="java plain">) { </code></div>
<div class="line number21 index20 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">nValue = qiuyu(Shang) + nValue; </code></div>
<div class="line number22 index21 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number23 index22 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">System.out.println(nValue); </code></div>
<div class="line number24 index23 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number25 index24 alt2"><code class="java spaces">&nbsp;</code>&nbsp;</div>
<div class="line number26 index25 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">/** </code></div>
<div class="line number27 index26 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">* 功能：对给定的M进制字符串对n求余。 </code></div>
<div class="line number28 index27 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">*&nbsp; </code></div>
<div class="line number29 index28 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">* @param MTempValue </code></div>
<div class="line number30 index29 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">* @param m </code></div>
<div class="line number31 index30 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">* @param n </code></div>
<div class="line number32 index31 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">* @return </code></div>
<div class="line number33 index32 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java preprocessor">*/</code></div>
<div class="line number34 index33 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java plain">String qiuyu(String MTempValue) { </code></div>
<div class="line number35 index34 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">Shang = </code><code class="java string">""</code><code class="java plain">; </code></div>
<div class="line number36 index35 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">int</code> <code class="java plain">temp = </code><code class="java value">0</code><code class="java plain">; </code></div>
<div class="line number37 index36 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">while</code> <code class="java plain">(MTempValue.length() &gt; </code><code class="java value">0</code><code class="java plain">) { </code></div>
<div class="line number38 index37 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">int</code> <code class="java plain">t = getIntFromStr(MTempValue.substring(</code><code class="java value">0</code><code class="java plain">, </code><code class="java value">1</code><code class="java plain">)); </code></div>
<div class="line number39 index38 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">MTempValue = MTempValue.substring(</code><code class="java value">1</code><code class="java plain">); </code></div>
<div class="line number40 index39 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">temp = temp * M + t; </code></div>
<div class="line number41 index40 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">Shang += getStrFromInt(temp / N); </code></div>
<div class="line number42 index41 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">temp = temp % N; </code></div>
<div class="line number43 index42 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number44 index43 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">while</code><code class="java plain">(Shang.length() &gt; </code><code class="java value">0</code> <code class="java plain">&amp;&amp; Shang.charAt(</code><code class="java value">0</code><code class="java plain">) == </code><code class="java string">'0'</code><code class="java plain">){ </code></div>
<div class="line number45 index44 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">Shang = Shang.substring(</code><code class="java value">1</code><code class="java plain">); </code></div>
<div class="line number46 index45 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number47 index46 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">return</code> <code class="java plain">getStrFromInt(temp); </code></div>
<div class="line number48 index47 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number49 index48 alt2"><code class="java spaces">&nbsp;</code>&nbsp;</div>
<div class="line number50 index49 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java keyword">int</code> <code class="java plain">getIntFromStr(String str){ </code></div>
<div class="line number51 index50 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">return</code> <code class="java plain">str.charAt(</code><code class="java value">0</code><code class="java plain">) &lt;= </code><code class="java string">'9'</code> <code class="java plain">&amp;&amp; str.charAt(</code><code class="java value">0</code><code class="java plain">) &gt;= </code><code class="java string">'0'</code><code class="java plain">?&nbsp; </code></div>
<div class="line number52 index51 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">str.charAt(</code><code class="java value">0</code><code class="java plain">) - </code><code class="java string">'0'</code> <code class="java plain">: str.charAt(</code><code class="java value">0</code><code class="java plain">) - </code><code class="java string">'a'</code> <code class="java plain">+ </code><code class="java value">10</code><code class="java plain">; </code></div>
<div class="line number53 index52 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number54 index53 alt1"><code class="java spaces">&nbsp;</code>&nbsp;</div>
<div class="line number55 index54 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java plain">String getStrFromInt(</code><code class="java keyword">int</code> <code class="java plain">value){ </code></div>
<div class="line number56 index55 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">String result = </code><code class="java keyword">null</code><code class="java plain">; </code></div>
<div class="line number57 index56 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">if</code><code class="java plain">(value&gt;=</code><code class="java value">0</code> <code class="java plain">&amp;&amp; value&lt;=</code><code class="java value">9</code><code class="java plain">) </code></div>
<div class="line number58 index57 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">result = String.valueOf((</code><code class="java keyword">char</code><code class="java plain">)(</code><code class="java string">'0'</code> <code class="java plain">+ value)); </code></div>
<div class="line number59 index58 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">else</code> <code class="java keyword">if</code><code class="java plain">(vlaue &gt; </code><code class="java value">9</code> <code class="java plain">&amp;&amp; value &lt;</code><code class="java value">36</code><code class="java plain">) </code></div>
<div class="line number60 index59 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">{ </code></div>
<div class="line number61 index60 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">result = String.valueOf((</code><code class="java keyword">char</code><code class="java plain">)(</code><code class="java string">'a'</code> <code class="java plain">+ value - </code><code class="java value">10</code><code class="java plain">)); </code></div>
<div class="line number62 index61 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number63 index62 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">else</code></div>
<div class="line number64 index63 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">{ </code></div>
<div class="line number65 index64 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">result = </code><code class="java string">"-1"</code><code class="java plain">;</code><code class="java comments">// 出错误了 </code></div>
<div class="line number66 index65 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number67 index66 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java keyword">return</code> <code class="java plain">result; </code></div>
<div class="line number68 index67 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">} </code></div>
<div class="line number69 index68 alt2"><code class="java plain">}</code></div></div></td></tr></tbody></table></div></div></div>
<p>赵大叔的算法好了不少，除了参数检查，大小写之外都很好。值得我们借鉴。&nbsp;</p><img src ="http://www.cppblog.com/mysileng/aggbug/200879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-08 16:16 <a href="http://www.cppblog.com/mysileng/archive/2013/06/08/200879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>求图两点之间所有路径</title><link>http://www.cppblog.com/mysileng/archive/2013/06/07/200845.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Fri, 07 Jun 2013 08:47:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/07/200845.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/200845.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/07/200845.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/200845.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/200845.html</trackback:ping><description><![CDATA[<p style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><br />求两定点之间的全部路径，其根本是一个涉及到搜索和回溯的问题。我们设计算法时所关心的首要问题是：按照何种顺序搜索和回溯才能保证路径可以不重不漏地被全部找到。<br />&nbsp;</span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">图的存储结构：邻接矩阵。<font face="Calibri">Arcs</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">工作结构：结点栈&nbsp;<font face="Calibri">mystack;</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">状态保存结构：&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p15" style="margin-left:36.0000pt; text-indent:-36.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">（1）&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">VertexStatus[]={0,0,0,1,1,</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">&#8230;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">}<font face="宋体">。当结点未进栈或者已经出栈，则其对应的状态为</font><font face="Calibri">0</font><font face="宋体">，否则状态为</font><font face="Calibri">1</font><font face="宋体">；</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p15" style="margin-left:36.0000pt; text-indent:-36.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">（2）&nbsp;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ArcStatus[][]={0,0,1,0,1</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">&#8230;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">..}<font face="宋体">当且仅当边的两个结点都在栈外时，边的状态才为</font><font face="Calibri">0</font><font face="宋体">，否则为</font><font face="Calibri">1</font><font face="宋体">。</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">注意我们只所以设计如上结点、边两个状态存储结构，就是依据于<font face="Calibri">path</font><font face="宋体">的定义，结点不重复，边不重复。具有边状态存储结构，也是我的算法与其他算法根本上的不同。</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">不失一般性，我们假设原点的编号最小为<font face="Calibri">0,</font><font face="宋体">目标点的编号最大</font><font face="Calibri">N</font><font face="宋体">。我们的问题转换成了，求最小编号的节点与最大编号的节点之间的所有路径。<br /><br /></font></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">P</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">aths={}//<font face="宋体">路径集合</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">VertexStatus[]={0};//<font face="宋体">全部置</font><font face="Calibri">0</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ArcStatus[][]={0};////<font face="宋体">全部置</font><font face="Calibri">0</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">mystack</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">.push(0);</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">VertexStatus[0]=1;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">W</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">hile(!mystack.empty())</span><span style="font-family: 宋体; font-size: 10.5pt;">{</span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">&nbsp; I</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">nt&nbsp;elem=&nbsp;mystack.top();//<font face="宋体">获得栈顶元素</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">&nbsp; if(elem==N)</span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">{</span><span style="font-family: 宋体;">//</span><font face="宋体" style="font-family: 宋体;">找到了一条路径</font></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">path</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">=Traverse(mystack);</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">Paths.add(path);</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">VertexStatus[elem]=0;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">UpdateArcStatus();//<font face="宋体">更新</font><font face="Calibri">ArcStatus[][]</font><font face="宋体">，使得所有两个端点都不在栈内的边的状态为</font><font face="Calibri">0</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">mystack</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">.pop();//<font face="宋体">移除栈顶元素<br /></font></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">&nbsp; }</span><span style="font-family: Calibri; font-size: 10.5pt; text-indent: 21pt;">else</span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">{</span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">i</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">=0;<br /></span><span style="text-indent: 21pt; font-size: 10.5pt; font-family: Calibri;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; F</span><span style="text-indent: 21pt; font-size: 10.5pt; font-family: 宋体;">or(;i&lt;N;i++)</span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">{&nbsp;<br />&nbsp; &nbsp; &nbsp; if(VertexStatus[i]=0&amp;&amp;ArcStatus[elem][i]=0&amp;&amp;Arcs.contain(elem,i))</span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">{</span></p><p class="p0" style="margin-left:21.0000pt; text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">VertexStatus[i]=1;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-left:21.0000pt; text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ArcStatus[elem][i]=1;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="margin-left:21.0000pt; text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">	</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">M</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ystack.push(i);//<font face="宋体">入栈<br /></font></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">&nbsp; &nbsp; break;<br /></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">&nbsp; }<br /></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">}<br /></span><span style="text-indent: 21pt; font-size: 10.5pt; font-family: Calibri;">if</span><span style="text-indent: 21pt; font-size: 10.5pt; font-family: 宋体;">(i=N)</span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">{</span><span style="font-family: 宋体;">//</span><font face="宋体" style="font-family: 宋体;">该节点没有符合要求的后续节点</font></p><p class="p0" style="margin-left:21.0000pt; text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">VertexStatus[elem]=0;</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">&nbsp; &nbsp; UpdateArcStaus();////<font face="宋体">更新</font><font face="Calibri">ArcStatus[][]</font><font face="宋体">，使得所有两个端点都不在栈内的边的状为</font><font face="Calibri">0</font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span></p><p class="p0" style="text-indent:21.0000pt; margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'Calibri'; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M</span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; ">ystack.pop();//<font face="宋体">出栈<br /></font></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">&nbsp; &nbsp; }<br /></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">&nbsp; &nbsp;}<br /></span><span style="font-family: 宋体; font-size: 10.5pt; text-indent: 21pt;">}</span></p><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><font face="宋体"><br /></font></span><span style="mso-spacerun:'yes'; font-size:10.5000pt; font-family:'宋体'; "><o:p></o:p></span><p>&nbsp;</p><p>&nbsp;</p><img src ="http://www.cppblog.com/mysileng/aggbug/200845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-07 16:47 <a href="http://www.cppblog.com/mysileng/archive/2013/06/07/200845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>进制数模式</title><link>http://www.cppblog.com/mysileng/archive/2013/06/06/200832.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Thu, 06 Jun 2013 13:57:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/06/200832.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/200832.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/06/200832.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/200832.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/200832.html</trackback:ping><description><![CDATA[<div>考虑n位二进制数，有多少个数中不存在两个相邻的1。例如，3位数中有5个数符合这一要求：000、001、010、100、101。&nbsp;</div><div>1、试找出其中的规律&nbsp;</div><div>2、请给出完整代码实现（参数输入代码可略）&nbsp;</div><div>3、试证明你找到的规律是正确的&nbsp;</div><div>1、 答：规律为2 n/2+2n-n/2-1。&nbsp;</div><div>2、 代码如下&nbsp;</div><div>#include&lt;cmath&gt;&nbsp;</div><div>using namespace std;&nbsp;</div><div>int Func(int n) {&nbsp;</div><div>&nbsp; if(n&lt;0) { &nbsp;return -1; }&nbsp;</div><div>&nbsp; if(n==0) { &nbsp;return 0; }&nbsp;</div><div>&nbsp; return pow(2,(n/2))+pow(2,((n-(n/2)))-1;</div><div>}&nbsp;</div><div>&nbsp;</div><div>3、 证明（构造法）&nbsp;</div><div>答：&nbsp;</div><div>1列出n位由1组成的2进制数a，111。。。。111；</div><div>2奇数位都用0取代得到数b，010。。。。010；&nbsp;</div><div>3偶数位也用0取代得到数c，101。。。。101；&nbsp;</div><div>4数b和数c中的任何一个1都可以被0取代，或不被取代，而构造出满足要求的数，且每个1的取代具有独立性。&nbsp;</div><div>5数b可以构造出2n/2个满足要求的数，同时数c可以构造出2n-n/2个满足要求的数。&nbsp;</div><div>6数b和数a都可以构造出全由0组成二进制数，因此统计存在一个重复。&nbsp;</div><div>7规律为2 n/2+2n-n/2-1；<br /><br />-------------------------------------------------------------------------------------------------<br /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">n位的二进制,比如3位:000&nbsp;001&nbsp;010&nbsp;100&nbsp;101</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;" /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">什么规律呢，假设n位二进制有f(n)种不相邻的组合，</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;" /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">从最左边的位置开始放，可以放0，也可以放1。</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;" /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">如果最左边放0，那么将不影响第二位的放置，从第二位放起，即有f(n-1)种。</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;" /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">如果最左边放1，那么第二位则只能放0，从第三位放起，即有f(n-2)种。</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;" /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">所以f(n)=f(n-1)+f(n-2)种。</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;" /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 24px; background-color: #f5f5f5;">另外f(1)=2(因为可以放0或者1),f(2)=3(因为可以是00,01,10)。</span><br /><br /><br /><br /><br /></div><img src ="http://www.cppblog.com/mysileng/aggbug/200832.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-06 21:57 <a href="http://www.cppblog.com/mysileng/archive/2013/06/06/200832.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图的一个题</title><link>http://www.cppblog.com/mysileng/archive/2013/05/26/200596.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Sun, 26 May 2013 02:40:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/05/26/200596.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/200596.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/05/26/200596.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/200596.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/200596.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体; font-size: 14px; line-height: 24px;">题目：一个单入口单出口的有向无环图中，要求在某些地方插入一些节点使得任何一条由起点到终点所经历的节点数相同，类似于下面的图，要求给出算法描述并分析时间复杂度。<br /><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130526103840.jpg" width="490" height="202" alt="" /><br /></span><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">如上图所示，节点A到C有两条路径，ABC这条路径经过了一个节点，而AC路径经过了0个节点，我们的算法所要做的事就是要在AC路径中间加入一个节点，然后ABC路径和ADC路径都经过了一个节点。<br /><br /></span><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">算法是这样的：对于每个节点维护一组信息，包括节点的层数（起始节点到该节点的路径长度，起始节点设为0）以及生成该长度的父节点，相对于右图，节点6维护的不经处理的信息就是：层数2来自节点3和节点4；节点7维护的不经处理的信息就是：层数3来自节点5和节点6以及层数2来自节点4；节点8的不经处理的信息是：层数4来自节点7，层数3来自节点7，层数2来自节点4。我们算法所要做的事就是最终使每个节点需要维护的层信息变为一个，即无论从那条路径到该节点，该节点所处的层数都是固定的。算法如下：</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">1、初始化起始节点的层数信息</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">2、从起始节点开始遍历每条路径，遇到每个节点生成一个维护信息</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">（1）如果此节点不存在维护信息，创建之；</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">（2）如果该节点存在维护信息，有两种情况：</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">（a）如果生成的维护信息的层数和原来已有的维护信息的层数是相同的，则合并这两个维护信息，比如对于例子中的图，节点5原来的维护信息为&#8220;层数3来自节点2&#8221;，然后从节点3到节点5生成的维护信息为&#8220;层数3来自节点3&#8221;，由于层数相同，我们可以将其合并为&#8220;层数3来自节点2和节点3&#8221;；</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">（b）如果生成的维护信息的层数和原来节点的维护信息的层数不一致，我们需要比较那一个的层数较大：</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">a.如果原来维护信息的层数较大，此时，我们只需要在生成此维护信息的节点与此节点之间插入一个新的节点，然后生成新节点的维护信息，然后从新节点开始（2）过程</span><br style="font-family: 宋体; font-size: 14px; line-height: 24px;" /><span style="font-family: 宋体; font-size: 14px; line-height: 24px;">b.如果新生成的维护信息的层数较大，将新生成的节点信息存入此节点，然后我们需要在生成原来维护信息的所有节点和此节点之间插入新节点，并且需要从所有的新插入节点开始（2）过程<br /><br /><br /><br /></span><img src ="http://www.cppblog.com/mysileng/aggbug/200596.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-05-26 10:40 <a href="http://www.cppblog.com/mysileng/archive/2013/05/26/200596.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>已知一个函数rand7()能够生成1-7的随机数，请给出一个函数rand10()，该函数能够生成1-10的随机数。</title><link>http://www.cppblog.com/mysileng/archive/2013/05/20/200426.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 20 May 2013 14:55:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/05/20/200426.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/200426.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/05/20/200426.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/200426.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/200426.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"><strong>题目：</strong></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">已知一个函数rand7()能够生成1-7的随机数，请给出一个函数，该函数能够生成1-10的随机数。</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"><br /></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"><strong>思路：</strong></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">假如已知一个函数能够生成1-49的随机数，那么如何以此生成1-10的随机数呢？</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"><br /></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"><strong>解法：</strong></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">该解法基于一种叫做拒绝采样的方法。主要思想是只要产生一个目标范围内的随机数，则直接返回。如果产生的随机数不在目标范围内，则丢弃该值，重新取样。由于目标范围内的数字被选中的概率相等，这样一个均匀的分布生成了。</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">显然rand7至少需要执行2次，否则产生不了1-10的数字。通过运行rand7两次，可以生成1-49的整数，</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><pre name="code" style="white-space: pre-wrap; word-wrap: break-word; margin-top: 0px; margin-bottom: 24px; padding: 10px; border: 1px solid #cccccc; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: #fff7f0; overflow: auto; width: 262.3999938964844px; line-height: 20.799999237060547px; color: #222222;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">   1  2  3  4  5  6  7 1</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">1  2  3  4  5  6  7</span> <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">2</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">8  9 10  1  2  3  4</span> <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">3</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">5  6  7  8  9 10  1</span> <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">4</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">2  3  4  5  6  7  8</span> <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">5</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">9 10  1  2  3  4  5</span> <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">6</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">6  7  8  9 10  *  *</span> <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">7</span>  <span style="color: maroon; margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">*  *  *  *  *  *  *</span></pre><strong style="font-family: Arial; font-size: 14px; line-height: 26px;">由于49不是10的倍数，所以我们需要丢弃一些值，我们想要的数字范围为1-40，不在此范围则丢弃并重新取样。</strong><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"><strong>代码：</strong></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><div bg_cpp"="" style="width: 1355.300048828125px; line-height: 26px;"><div><div><strong>[cpp]</strong>&nbsp;<a href="http://blog.csdn.net/ssjhust123/article/details/7753012#" title="view plain" style="background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-position: 0% 0%; background-repeat: no-repeat no-repeat;">view plain</a><a href="http://blog.csdn.net/ssjhust123/article/details/7753012#" title="copy" style="background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-position: 0% 0%; background-repeat: no-repeat no-repeat;">copy</a><div style="position: absolute; left: 377px; top: 942px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_1" align="center" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&amp;width=18&amp;height=18" wmode="transparent"></div></div></div><ol start="1"><li style="line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;rand10()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;row,&nbsp;col,&nbsp;idx;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;do&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;row&nbsp;=&nbsp;rand7();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;=&nbsp;rand7();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;idx&nbsp;=&nbsp;col&nbsp;+&nbsp;(row-1)*7;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;}&nbsp;while&nbsp;(idx&nbsp;&gt;&nbsp;40);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;return&nbsp;1&nbsp;+&nbsp;(idx-1)%10;&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li></ol></div><br style="font-family: Arial; font-size: 14px; line-height: 26px;" /><span style="font-family: Arial; font-size: 14px; line-height: 26px;">由于row范围为1-7，col范围为1-7，这样idx值范围为1-49。大于40的值被丢弃，这样剩下1-40范围内的数字，通过取模返回。下面计算一下得到一个满足1-40范围的数需要进行取样的次数的期望值：</span><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><pre style="white-space: pre-wrap; word-wrap: break-word; margin-top: 0px; margin-bottom: 24px; padding: 10px; border: 1px solid #cccccc; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: #fff7f0; overflow: auto; line-height: 20.799999237060547px; color: #222222;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">E(# calls to rand7)</span> = 2 * (40/49) +                       4 * (9/49) * (40/49) +                       6 * (9/49)<sup style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 10px; background-color: transparent; bottom: 1ex; height: 0px; line-height: 1; position: static;">2</sup> * (40/49) +                       ...                        <span style="font-size: 10px; margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; background-color: transparent;"><sub style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 10px; background-color: transparent; top: 0.5ex; height: 0px; line-height: 1; position: static;">&#8734;</sub></span>                     = <span style="font-size: 18px; margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; background-color: transparent;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 11.199999809265137px; vertical-align: baseline; background-color: transparent;">&#8721;</span></span> 2k * (9/49)<sup style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 10px; background-color: transparent; bottom: 1ex; height: 0px; line-height: 1; position: static;">k-1</sup> * (40/49)                       <span style="font-size: 10px; margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; background-color: transparent;">k=1</span>                      = (80/49) / (1 - 9/49)<sup style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 10px; background-color: transparent; bottom: 1ex; height: 0px; line-height: 1; position: static;">2</sup>                     = <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">2.45</span></pre><strong style="font-family: Arial; font-size: 14px; line-height: 26px;">优化：</strong><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">上面的方法大概需要2.45次调用rand7函数才能得到1个1-10范围的数，下面可以进行再度优化。</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">对于大于40的数，我们不必马上丢弃，可以对41-49的数减去40可得到1-9的随机数，而rand7可生成1-7的随机数，这样可以生成1-63的随机数。对于1-60我们可以直接返回，而61-63则丢弃，这样需要丢弃的数只有3个，相比前面的9个，效率有所提高。而对于61-63的数，减去60后为1-3，rand7产生1-7，这样可以再度利用产生1-21的数，对于1-20我们则直接返回，对于21则丢弃。这时，丢弃的数就只有1个了，优化又进一步。当然这里面对rand7的调用次数也是增加了的。代码如下：</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><div bg_cpp"="" style="width: 1355.300048828125px; line-height: 26px;"><div><div><strong>[cpp]</strong>&nbsp;<a href="http://blog.csdn.net/ssjhust123/article/details/7753012#" title="view plain" style="background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-position: 0% 0%; background-repeat: no-repeat no-repeat;">view plain</a><a href="http://blog.csdn.net/ssjhust123/article/details/7753012#" title="copy" style="background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-position: 0% 0%; background-repeat: no-repeat no-repeat;">copy</a><div style="position: absolute; left: 377px; top: 1624px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_2" align="center" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&amp;width=18&amp;height=18" wmode="transparent"></div></div></div><ol start="1"><li style="line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;rand10Imp()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;a,&nbsp;b,&nbsp;idx;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;while&nbsp;(true)&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;rand7();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;rand7();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;idx&nbsp;=&nbsp;b&nbsp;+&nbsp;(a-1)*7;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(idx&nbsp;&lt;=&nbsp;40)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1&nbsp;+&nbsp;(idx-1)%10;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;idx-40;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;rand7();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;get&nbsp;uniform&nbsp;dist&nbsp;from&nbsp;1&nbsp;-&nbsp;63&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;idx&nbsp;=&nbsp;b&nbsp;+&nbsp;(a-1)*7;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(idx&nbsp;&lt;=&nbsp;60)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1&nbsp;+&nbsp;(idx-1)%10;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;idx-60;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;rand7();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;get&nbsp;uniform&nbsp;dist&nbsp;from&nbsp;1-21&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;idx&nbsp;=&nbsp;b&nbsp;+&nbsp;(a-1)*7;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(idx&nbsp;&lt;=&nbsp;20)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1&nbsp;+&nbsp;(idx-1)%10;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li></ol></div><span style="font-family: Arial; font-size: 14px; line-height: 26px;">下面计算下优化后方法的调用rand7函数的期望次数：</span><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; line-height: 26px;"></p><pre style="white-space: pre-wrap; word-wrap: break-word; margin-top: 0px; margin-bottom: 24px; padding: 10px; border: 1px solid #cccccc; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: #fff7f0; overflow: auto; line-height: 20.799999237060547px; color: #222222;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">E(# calls to rand7)</span> = 2 * (40/49) +                       3 * (9/49) * (60/63) +                       4 * (9/49) * (3/63) * (20/21) +                         (9/49) * (3/63) * (1/21) *                       [ 6 * (40/49) +                         7 * (9/49) * (60/63) +                         8 * (9/49) * (3/63) * (20/21) ] +                        ((9/49) * (3/63) * (1/21))<sup style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 10px; background-color: transparent; bottom: 1ex; height: 0px; line-height: 1; position: static;">2</sup> *                       [ 10 * (40/49) +                         11 * (9/49) * (60/63) +                         12 * (9/49) * (3/63) * (20/21) ] +                       ...                      = <span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-size: 12.800000190734863px; vertical-align: baseline; background-color: transparent;">2.2123</span></pre><span style="font-family: Arial; font-size: 14px; line-height: 26px;">这里期望次数为2.21，比起未优化的2.45次减少了大概10%。</span><img src ="http://www.cppblog.com/mysileng/aggbug/200426.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-05-20 22:55 <a href="http://www.cppblog.com/mysileng/archive/2013/05/20/200426.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二叉树的非递归遍历</title><link>http://www.cppblog.com/mysileng/archive/2013/05/03/199948.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Fri, 03 May 2013 11:51:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/05/03/199948.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/199948.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/05/03/199948.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/199948.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/199948.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自：http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/05/03/199948.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/199948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-05-03 19:51 <a href="http://www.cppblog.com/mysileng/archive/2013/05/03/199948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Skip List（跳跃表）原理详解与实现</title><link>http://www.cppblog.com/mysileng/archive/2013/04/06/199159.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Sat, 06 Apr 2013 11:55:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/04/06/199159.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/199159.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/04/06/199159.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/199159.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/199159.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文内容框架： &#167;1   Skip List 介绍 &#167;2   Skip List 定义以及构造步骤 &#167;3  Skip List 完整实现  &#167;4  Skip List 概率分析 &#167;5  小结&nbsp;&nbsp;&nbsp;&#167;1   Skip List 介绍&nbsp;	Skip List是一种随机化的数据结构，基于并联的链表，其效率可...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/04/06/199159.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/199159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-04-06 19:55 <a href="http://www.cppblog.com/mysileng/archive/2013/04/06/199159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最长上升子序列  O(nlogn)解法 (转)</title><link>http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Fri, 30 Nov 2012 09:44:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/195841.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/195841.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/195841.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">最近在做单调队列，发现了最长上升子序列O(nlogn)的求法也有利用单调队列的思想。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 最长递增子序列问题：在一列数中寻找一些数，这些数满足：任意两个数a[i]和a[j]，若i&lt;j，必有a[i]&lt;a[j]，这样最长的子序列称为最长递增子序列。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp; 设dp[i]表示以i为结尾的最长递增子序列的长度，则状态转移方程为：</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">dp[i] = max{dp[j]+1}, 1&lt;=j&lt;i,a[j]&lt;a[i].</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp; 这样简单的复杂度为O(n^2)，其实还有更好的方法。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp; 考虑两个数a[x]和a[y]，x&lt;y且a[x]&lt;a[y],且dp[x]=dp[y]，当a[t]要选择时，到底取哪一个构成最优的呢？显然选取a[x]更有潜力，因为可能存在a[x]&lt;a[z]&lt;a[y]，这样a[t]可以获得更优的值。在这里给我们一个启示，当dp[t]一样时，尽量选择更小的a[x].</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 按dp[t]=k来分类，只需保留dp[t]=k的所有a[t]中的最小值，设d[k]记录这个值，d[k]=min{a[t],dp[t]=k}。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 这时注意到d的两个特点（<span style="color: #ff0000;">重要</span>）：</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;"><strong>1.</strong>&nbsp;d[k]在计算过程中单调不升；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;"><strong>2.</strong>&nbsp;d数组是有序的，d[1]&lt;d[2]&lt;..d[n]。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 利用这两个性质，可以很方便的求解：</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">1. 设当前已求出的最长上升子序列的长度为len（初始时为1），每次读入一个新元素x：</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">2. 若x&gt;d[len]，则直接加入到d的末尾，且len++；（利用性质2）</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;"><span style="font-size: small;">&nbsp;&nbsp; 否则，在d中二分查找，找到第一个比x小的数d[k]，并d[k+1]=x，在这里x&lt;=d[k+1]一定成立（性质1,2）。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;">&nbsp;</p><div id="" style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; background-color: #ffffff; width: 679px; margin-left: 9px; padding-right: 1px; padding-bottom: 1px; padding-left: 1px; word-break: break-all; word-wrap: break-word; line-height: 25.200000762939453px;"><ol start="1" style="font-size: 1em; line-height: 1.4em; margin-left: 0px; padding-top: 2px; padding-bottom: 2px; border: 1px solid #d1d7dc; color: #2b91af;"><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">/**</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">最长递增子序列O(nlogn)算法：</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">状态转移方程：f[i]&nbsp;=&nbsp;max{f[i],f[j]+1},1&lt;=j&lt;i,a[j]&lt;a[i].</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">分析：加入x&lt;y,f[x]&gt;=f[y],则x相对于y更有潜力。</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">首先根据f[]值分类，记录满足f[t]=k的最小的值a[t],记d[k]=min{a[t]},f[t]=k.</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;1.发现d[k]在计算过程中单调不上升</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;2.d[1]&lt;d[2]&lt;...&lt;d[k]&nbsp;(反证)&nbsp;1&nbsp;2&nbsp;3&nbsp;8&nbsp;4&nbsp;7</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">解法：</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">1.&nbsp;设当前最长递增子序列为len,考虑元素a[i];</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">2.&nbsp;若d[len]&lt;a[i],则len++，并将d[len]=a[i];</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">&nbsp;&nbsp;&nbsp;否则,在d[0-len]中二分查找,找到第一个比它小的元素d[k],并d[k+1]=a[i].()</span>&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="width: auto; border-width: 0px;">*/</span>&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">#include&nbsp;&lt;iostream&gt;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">#include&nbsp;&lt;cstdio&gt;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">#include&nbsp;&lt;cstring&gt;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">using</span>&nbsp;<span style="color: #7f0055;">namespace</span>&nbsp;std;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">const</span>&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;N&nbsp;=&nbsp;41000;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;a[N];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="width: auto; border-width: 0px;">//a[i]&nbsp;原始数据</span>&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;d[N];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="width: auto; border-width: 0px;">//d[i]&nbsp;长度为i的递增子序列的最小值</span>&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;BinSearch(<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;key,&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>*&nbsp;d,&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;low,&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;high)&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">{&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">while</span>(low&lt;=high)&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;mid&nbsp;=&nbsp;(low+high)&gt;&gt;1;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">if</span>(key&gt;d[mid]&nbsp;&amp;&amp;&nbsp;key&lt;=d[mid+1])&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">return</span>&nbsp;mid;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">else</span>&nbsp;<span style="color: #7f0055;">if</span>(key&gt;d[mid])&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;low&nbsp;=&nbsp;mid+1;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">else</span>&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;high&nbsp;=&nbsp;mid-1;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">return</span>&nbsp;0;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">}&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;LIS(<span style="color: #2e8b57; font-weight: bold;">int</span>*&nbsp;a,&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;n,&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>*&nbsp;d)&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">{&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;i,j;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;d[1]&nbsp;=&nbsp;a[1];&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;len&nbsp;=&nbsp;1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="width: auto; border-width: 0px;">//递增子序列长度</span>&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">for</span>(i&nbsp;=&nbsp;2;&nbsp;i&nbsp;&lt;=&nbsp;n;&nbsp;i++)&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">if</span>(d[len]&lt;a[i])&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;=&nbsp;++len;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">else</span>&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;=&nbsp;BinSearch(a[i],d,1,len)&nbsp;+&nbsp;1;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d[j]&nbsp;=&nbsp;a[i];&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">return</span>&nbsp;len;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">}&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;main()&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">{&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;t;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;p;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;scanf("%d",&amp;t);&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">while</span>(t--)&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf("%d",&amp;p);&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">for</span>(<span style="color: #2e8b57; font-weight: bold;">int</span>&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;=&nbsp;p;&nbsp;i++)&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf("%d",&amp;a[i]);&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",LIS(a,p,d));&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055;">return</span>&nbsp;0;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">}&nbsp;&nbsp;</li></ol></div><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff;">&nbsp;</p><img src ="http://www.cppblog.com/mysileng/aggbug/195841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-11-30 17:44 <a href="http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ题目分类(转)</title><link>http://www.cppblog.com/mysileng/archive/2012/11/26/195696.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 26 Nov 2012 05:00:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/11/26/195696.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/195696.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/11/26/195696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/195696.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/195696.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">转贴 ACM的算法（觉得很好，有层次感）<br />OJ上的一些水题(可用来练手和增加自信)&nbsp;<br />(poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><br />初期:</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">一.基本算法:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)枚举. (poj1753,poj2965)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)贪心(poj1328,poj2109,poj2586)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)递归和分治法.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)递推.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (5)构造法.(poj3295)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)&nbsp;<br />二.图算法:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)图的深度优先遍历和广度优先遍历.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)最小生成树算法(prim,kruskal)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1789,poj2485,poj1258,poj3026)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)拓扑排序 (poj1094)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (6)最大流的增广路算法(KM算法). (poj1459,poj3436)&nbsp;<br />三.数据结构.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)串 (poj1035,poj3080,poj1936)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)简单并查集的应用.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (5)哈夫曼树(poj3253)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (6)堆&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (7)trie树(静态建树、动态建树) (poj2513)&nbsp;<br />四.简单搜索&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)&nbsp;<br />五.动态规划&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)背包问题. (poj1837,poj1276)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)型如下表的简单DP(可参考lrj的书 page149):&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3176,poj1080,poj1159)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)&nbsp;<br />六.数学&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)组合数学:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.加法原理和乘法原理.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.排列组合.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.递推关系.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (POJ3252,poj1850,poj1019,poj1942)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)数论.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.素数与整除问题&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.进制位.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.同余模运算.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj2635, poj3292,poj1845,poj2115)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)计算方法.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)&nbsp;<br />七.计算几何学.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)几何公式.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; (3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1408,poj1584)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)凸包. (poj2187,poj1113)</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><br />中级:</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">一.基本算法:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)C++的标准模版库的应用. (poj3096,poj3007)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)&nbsp;<br />二.图算法:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)差分约束系统的建立和求解. (poj1201,poj2983)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)最小费用最大流(poj2516,poj2195)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)双连通分量(poj2942)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)强连通分支及其缩点.(poj2186)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (5)图的割边和割点(poj3352)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (6)最小割模型、网络流规约(poj3308, )&nbsp;<br />三.数据结构.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)静态二叉检索树. (poj2482,poj2352)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)树状树组(poj1195,poj3321)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)RMQ. (poj3264,poj3368)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (5)并查集的高级应用. (poj1703,2492)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (6)KMP算法. (poj1961,poj2406)&nbsp;<br />四.搜索&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)最优化剪枝和可行性剪枝&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)搜索的技巧和优化 (poj3411,poj1724)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)记忆化搜索(poj3373,poj1691)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />五.动态规划&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)较为复杂的动态规划(如动态规划解特别的施行商问题等)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)记录状态的动态规划. (POJ3254,poj2411,poj1185)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)树型动态规划(poj2057,poj1947,poj2486,poj3140)&nbsp;<br />六.数学&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (1)组合数学:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.容斥原理.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.抽屉原理.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.递推关系和母函数.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (2)数学.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.概率问题. (poj3071,poj3440)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (3)计算方法.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.0/1分数规划. (poj2976)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.三分法求解单峰(单谷)的极值.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.矩阵法(poj3150,poj3422,poj3070)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.迭代逼近(poj3301)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (4)随机化算法(poj3318,poj2454)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; (5)杂题.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1870,poj3296,poj3286,poj1095)&nbsp;<br />七.计算几何学.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)坐标离散化.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)多边形的内核(半平面交)(poj3130,poj3335)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429<br />)</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><br />高级:&nbsp;<br />一.基本算法要求:&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)代码快速写成,精简但不失风格&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)保证正确性和高效性. poj3434&nbsp;<br />二.图算法:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)度限制最小生成树和第K最短路. (poj1639)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)最优比率生成树. (poj2728)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)最小树形图(poj3164)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5)次小生成树.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6)无向图、有向图的最小环&nbsp;&nbsp;&nbsp;&nbsp;<br />三.数据结构.&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)trie图的建立和应用. (poj2778)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算法<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RMQ+dfs)).(poj1330)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移<br />的&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目的). (poj2823)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)左偏树(可合并堆).&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5)后缀树(非常有用的数据结构,也是赛区考题的热点).&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3415,poj3294)&nbsp;<br />四.搜索&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储<br />状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大<br />、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)&nbsp;<br />五.动态规划&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)需要用数据结构优化的动态规划.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj2754,poj3378,poj3017)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)四边形不等式理论.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)较难的状态DP(poj3133)&nbsp;<br />六.数学&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)组合数学.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.MoBius反演(poj2888,poj2154)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.偏序关系理论.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)博奕论.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.极大极小过程(poj3317,poj1085)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.Nim问题.&nbsp;<br />七.计算几何学.&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)半平面求交(poj3384,poj2540)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)可视图的建立(poj2966)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)点集最小圆覆盖.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)对踵点(poj2079)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 八.综合题.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263<br />)</p><img src ="http://www.cppblog.com/mysileng/aggbug/195696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-11-26 13:00 <a href="http://www.cppblog.com/mysileng/archive/2012/11/26/195696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最小堆&amp;&amp;最大堆的实现(c++)(转)</title><link>http://www.cppblog.com/mysileng/archive/2012/11/19/195384.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 19 Nov 2012 13:09:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/11/19/195384.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/195384.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/11/19/195384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/195384.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/195384.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最小堆：Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->template&lt;class&nbsp;T&gt;class&nbsp;MinHeap&nbsp;{public:&nbsp;&nbsp;&nbsp;&nbsp;MinHeap(int&nb...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2012/11/19/195384.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/195384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-11-19 21:09 <a href="http://www.cppblog.com/mysileng/archive/2012/11/19/195384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全排列算法及其C++实现(转)</title><link>http://www.cppblog.com/mysileng/archive/2012/11/05/194635.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 05 Nov 2012 13:01:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/11/05/194635.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/194635.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/11/05/194635.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/194635.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/194635.html</trackback:ping><description><![CDATA[<div><h3 style="margin: 0px; padding: 0px; color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><span style="color: #990000; ">第十六章、全排列问题</span></h3><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">53.字符串的排列。<br />题目：输入一个字符串，打印出该字符串中字符的所有排列。<br />例如输入字符串abc，则输出由字符a、b、c 所能排列出来的所有字符串<br />abc、acb、bac、bca、cab 和cba。</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; ">&nbsp; &nbsp; 分析：此题最初整理于去年的微软面试100题中第53题，第二次整理于<a href="http://blog.csdn.net/v_JULY_v/archive/2011/04/10/6313257.aspx" target="_blank" style="color: #220000; text-decoration: none; ">微软、Google等公司非常好的面试题及解答[第61-70题]</a>&nbsp;第67题。无独有偶，这个问题今年又出现于今年的2011.10.09百度笔试题中。ok，接下来，咱们先好好分析这个问题。<br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "></p><ul style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><li>一、递归实现<br />从集合中依次选出每一个元素，作为排列的第一个元素，然后对剩余的元素进行全排列，如此递归处理，从而得到所有元素的全排列。以对字符串abc进行全排列为例，我们可以这么做：以abc为例<br />固定a，求后面bc的排列：abc，acb，求好后，a和b交换，得到bac<br />固定b，求后面ac的排列：bac，bca，求好后，c放到第一位置，得到cba<br />固定c，求后面ba的排列：cba，cab。代码可如下编写所示：</li></ul><div style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff; "><ol class="dp-cpp" style="padding: 0px; margin: 0px 0px 1px; color: #5c5c5c; border-style: none; font-family: Consolas, 'Courier New', Courier, mono, serif; list-style-type: none !important; background-color: #e7e5dc; "><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; "><span style="padding: 0px; margin: 0px; border-style: none; "><strong>template</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;&lt;</span><span style="padding: 0px; margin: 0px; border-style: none; "><strong>typename</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;T&gt;&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; "><span style="padding: 0px; margin: 0px; border-style: none; "><strong>void</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;CalcAllPermutation_R(T&nbsp;perm[],&nbsp;</span><span style="color: #2e8b57; padding: 0px; margin: 0px; border-style: none; "><strong>int</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;first,&nbsp;</span><span style="color: #2e8b57; padding: 0px; margin: 0px; border-style: none; "><strong>int</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;num)&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">{&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>if</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(num&nbsp;&lt;=&nbsp;1)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>return</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">;&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>for</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(</span><span style="color: #2e8b57; padding: 0px; margin: 0px; border-style: none; "><strong>int</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;i&nbsp;=&nbsp;first;&nbsp;i&nbsp;&lt;&nbsp;first&nbsp;+&nbsp;num;&nbsp;++i)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(perm[i],&nbsp;perm[first]);&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CalcAllPermutation_R(perm,&nbsp;first&nbsp;+&nbsp;1,&nbsp;num&nbsp;-&nbsp;1);&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(perm[i],&nbsp;perm[first]);&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">} &nbsp;</span></li></ol>&nbsp; &nbsp; 或者如此编写，亦可：<div class="dp-highlighter bg_cpp" style="border: 1px dashed #999999; background-color: #f5f5f5; width: 687.0499877929688px; "><ol start="1" class="dp-cpp" style="margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-bottom: 5px; position: relative; "><li class="alt" style="border-left-style: none; line-height: 13px; "><span class="keyword" style="color: #0000ff; ">void</span>&nbsp;Permutation(<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>*&nbsp;pStr,&nbsp;<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>*&nbsp;pBegin);&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; "><span class="keyword" style="color: #0000ff; ">void</span>&nbsp;Permutation(<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>*&nbsp;pStr)&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">{&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permutation(pStr,&nbsp;pStr);&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">}&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; "><span class="keyword" style="color: #0000ff; ">void</span>&nbsp;Permutation(<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>*&nbsp;pStr,&nbsp;<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>*&nbsp;pBegin)&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">{&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="color: #0000ff; ">if</span>(!pStr&nbsp;||&nbsp;!pBegin)&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="color: #0000ff; ">return</span>;&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="color: #0000ff; ">if</span>(*pBegin&nbsp;==&nbsp;<span class="string" style="color: #009900; ">'\0'</span>)&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="string" style="color: #009900; ">"%s\n"</span>,&nbsp;pStr);&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="color: #0000ff; ">else</span>&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="color: #0000ff; ">for</span>(<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>*&nbsp;pCh&nbsp;=&nbsp;pBegin;&nbsp;*pCh&nbsp;!=&nbsp;<span class="string" style="color: #009900; ">'\0'</span>;&nbsp;++&nbsp;pCh)&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment" style="color: #999999; ">//&nbsp;swap&nbsp;pCh&nbsp;and&nbsp;pBegin</span>&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes" style="color: #2e8b57; font-weight: bold; ">char</span>&nbsp;temp&nbsp;=&nbsp;*pCh;&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pCh&nbsp;=&nbsp;*pBegin;&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pBegin&nbsp;=&nbsp;temp;&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Permutation(pStr,&nbsp;pBegin&nbsp;+&nbsp;1);&nbsp;&nbsp;&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment" style="color: #999999; ">//&nbsp;restore&nbsp;pCh&nbsp;and&nbsp;pBegin</span>&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;*pCh;&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pCh&nbsp;=&nbsp;*pBegin;&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pBegin&nbsp;=&nbsp;temp;&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li class="" style="border-left-style: none; line-height: 13px; ">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li class="alt" style="border-left-style: none; line-height: 13px; ">}&nbsp;&nbsp;</li></ol></div><ul><li>二、字典序排列<br />把升序的排列（当然，也可以实现为降序）作为当前排列开始，然后依次计算当前排列的下一个字典序排列。<br />对当前排列从后向前扫描，找到一对为升序的相邻元素，记为i和j（i &lt; j）。如果不存在这样一对为升序的相邻元素，则所有排列均已找到，算法结束；否则，重新对当前排列从后向前扫描，找到第一个大于i的元素k，交换i和k，然后对从j开始到结束的子序列反转，则此时得到的新排列就为下一个字典序排列。这种方式实现得到的所有排列是按字典序有序的，这也是C++ STL算法next_permutation的思想。算法实现如下：</li></ul><div><ol class="dp-cpp" style="padding: 0px; margin: 0px 0px 1px; color: #5c5c5c; border-style: none; font-family: Consolas, 'Courier New', Courier, mono, serif; list-style-type: none !important; background-color: #e7e5dc; "><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; "><span style="padding: 0px; margin: 0px; border-style: none; "><strong>template</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;&lt;</span><span style="padding: 0px; margin: 0px; border-style: none; "><strong>typename</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;T&gt;&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; "><span style="padding: 0px; margin: 0px; border-style: none; "><strong>void</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;CalcAllPermutation(T&nbsp;perm[],&nbsp;</span><span style="color: #2e8b57; padding: 0px; margin: 0px; border-style: none; "><strong>int</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;num)&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">{&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>if</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(num&nbsp;&lt;&nbsp;1)&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>return</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">;&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>while</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(</span><span style="padding: 0px; margin: 0px; border-style: none; "><strong>true</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; padding: 0px; margin: 0px; border-style: none; "><strong>int</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;i;&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>for</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(i&nbsp;=&nbsp;num&nbsp;-&nbsp;2;&nbsp;i&nbsp;&gt;=&nbsp;0;&nbsp;--i)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>if</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(perm[i]&nbsp;&lt;&nbsp;perm[i&nbsp;+&nbsp;1])&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>break</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">;&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>if</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(i&nbsp;&lt;&nbsp;0)&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>break</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">;&nbsp;&nbsp;</span><span style="padding: 0px; margin: 0px; border-style: none; ">//&nbsp;已经找到所有排列</span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2e8b57; padding: 0px; margin: 0px; border-style: none; "><strong>int</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;k;&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>for</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(k&nbsp;=&nbsp;num&nbsp;-&nbsp;1;&nbsp;k&nbsp;&gt;&nbsp;i;&nbsp;--k)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>if</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">&nbsp;(perm[k]&nbsp;&gt;&nbsp;perm[i])&nbsp;&nbsp;</span></span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding: 0px; margin: 0px; border-style: none; "><strong>break</strong></span><span style="padding: 0px; margin: 0px; border-style: none; ">;&nbsp;&nbsp;</span></span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(perm[i],&nbsp;perm[k]);&nbsp;&nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reverse(perm&nbsp;+&nbsp;i&nbsp;+&nbsp;1,&nbsp;perm&nbsp;+&nbsp;num);&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></li><li style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; line-height: 18px; list-style-type: none !important; background-color: #f8f8f8; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt" style="border-width: 0px; padding: 0px 3px 0px 10px !important; margin: 0px; border-left-style: solid; line-height: 18px; list-style-type: none !important; background-color: #ffffff; "><span style="color: black; padding: 0px; margin: 0px; border-style: none; ">} &nbsp;</span></li></ol><div><span style="font-family: SimSun; "><span style="line-height: 25px; ">&nbsp; 扩展：如果不是求字符的所有排列，而是求字符的所有组合，应该怎么办呢？当输入的字符串中含有相同的字符串时，相同的字符交换位置是不同的排列，但是同一个组合。举个例子，如果输入abc，它的组合有a、b、c、ab、ac、bc、abc<br /><br />转自</span></span>
<a href="http://blog.csdn.net/v_july_v/article/details/6879101">http://blog.csdn.net/v_july_v/article/details/6879101</a>
</div></div></div><span style="font-family: Arial; line-height: 26px; "><h3></h3><div><span style="color: #ff0000; "></span></div></span></div><img src ="http://www.cppblog.com/mysileng/aggbug/194635.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-11-05 21:01 <a href="http://www.cppblog.com/mysileng/archive/2012/11/05/194635.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>红黑树（转）</title><link>http://www.cppblog.com/mysileng/archive/2012/09/18/191149.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 18 Sep 2012 12:32:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/09/18/191149.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/191149.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/09/18/191149.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/191149.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/191149.html</trackback:ping><description><![CDATA[<font class="Apple-style-span" face="'Microsoft YaHei'"><span class="Apple-style-span" style="font-size: 20px; line-height: 30px;"><div><span style="font-family: Arial; font-size: 14px; line-height: 26px; color: #000000; "><h2><span style="font-family: 黑体; ">红黑树的平衡</span></h2><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">红黑树首先是一棵二叉查找树，它每个结点都被标上了颜色（红色或黑色），红黑树满足以下</span>5<span style="font-family: 宋体; ">个性质：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>1、&nbsp;</strong><strong><span style="font-family: 宋体; ">每个结点的颜色只能是红色或黑色。</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>2、&nbsp;</strong><strong><span style="font-family: 宋体; ">根结点是黑色的。</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>3、&nbsp;</strong><strong><span style="font-family: 宋体; ">每个叶子结点都带有两个空的黑色结点（被称为黑哨兵），如果一个结点</span>n</strong><strong><span style="font-family: 宋体; ">的只有一个左孩子，那么</span>n</strong><strong><span style="font-family: 宋体; ">的右孩子是一个黑哨兵；如果结点</span>n</strong><strong><span style="font-family: 宋体; ">只有一个右孩子，那么</span>n</strong><strong><span style="font-family: 宋体; ">的左孩子是一个黑哨兵。</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>4、&nbsp;</strong><strong><span style="font-family: 宋体; ">如果一个结点是红的，则它的两个儿子都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>5、&nbsp;</strong><strong><span style="font-family: 宋体; ">对于每个结点来说，从该结点到其子孙叶结点的所有路径上包含相同数目的黑结点。</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">红黑树的这</span>5<span style="font-family: 宋体; ">个性质中，第</span>3<span style="font-family: 宋体; ">点是比较难理解的，但它却非常有必要。我们看图</span>1<span style="font-family: 宋体; ">中的左边这张图，如果不使用黑哨兵，它完全满足红黑树性质，结点</span>50<span style="font-family: 宋体; ">到两个叶结点</span>8<span style="font-family: 宋体; ">和叶结点</span>82<span style="font-family: 宋体; ">路径上的黑色结点数都为</span>2<span style="font-family: 宋体; ">个。但如果加入黑哨兵后（如图</span>1<span style="font-family: 宋体; ">右图中的小黑圆点），叶结点的个数变为</span>8<span style="font-family: 宋体; ">个黑哨兵，根结点</span>50<span style="font-family: 宋体; ">到这</span>8<span style="font-family: 宋体; ">个叶结点路径上的黑高度就不一样了，所以它并不是一棵红黑树。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb01.jpg" border="0" alt="" width="428" height="160" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">要看真正的红黑树请在以上动画中添加几个结点，看看是否满足以上性质。</span></p><h2><a name="t2" style="color: rgb(255, 153, 0); text-decoration: none; "></a><span style="font-family: 黑体; ">红黑树的旋转操作</span></h2><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">红黑树的旋转操作和</span>AVL<span style="font-family: 宋体; ">树一样，分为</span>LL<span style="font-family: 宋体; ">、</span>RR<span style="font-family: 宋体; ">、</span>LR<span style="font-family: 宋体; ">、</span>RL<span style="font-family: 宋体; ">四种旋转类型，差别在于旋转完成后改变的是结点的颜色，而不是平衡因子。旋转动画演示请参考</span>AVL<span style="font-family: 宋体; ">这篇文章中的</span>Flash<span style="font-family: 宋体; ">动画：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html</p><h2><a name="t3" style="color: rgb(255, 153, 0); text-decoration: none; "></a><span style="font-family: 黑体; ">红黑树上结点的插入</span></h2><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">在讨论红黑树的插入操作之前必须要明白，任何一个即将插入的新结点的初始颜色都为红色。这一点很容易理解，因为插入黑点会增加某条路径上黑结点的数目，从而导致整棵树黑高度的不平衡。但如果新结点父结点为红色时（如图</span>2<span style="font-family: 宋体; ">所示），将会违返红黑树性质：一条路径上不能出现相邻的两个红色结点。这时就需要通过一系列操作来使红黑树保持平衡。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb02.jpg" border="0" alt="" width="339" height="140" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">为了清楚地表示插入操作以下在结点中使用&#8220;新&#8221;字表示一个新插入的结点；使用&#8220;父&#8221;字表示新插入点的父结点；使用&#8220;叔&#8221;字表示&#8220;父&#8221;结点的兄弟结点；使用&#8220;祖&#8221;字表示&#8220;父&#8221;结点的父结点。插入操作分为以下几种情况：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 14pt; ">1</span></strong><strong><span style="font-family: 宋体; font-size: 14pt; ">、</span></strong><strong><span style="font-family: 宋体; font-size: 14pt; ">黑父</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">如图</span>3<span style="font-family: 宋体; ">所示，如果新点的父结点为黑色结点，那么插入一个红点将不会影响红黑树的平衡，此时插入操作完成。红黑树比</span>AVL<span style="font-family: 宋体; ">树优秀的地方之一在于黑父的情况比较常见，从而使红黑树需要旋转的几率相对</span>AVL<span style="font-family: 宋体; ">树来说会少一些。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb03.jpg" border="0" alt="" width="191" height="89" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 14pt; ">2</span></strong><strong><span style="font-family: 宋体; font-size: 14pt; ">．红父</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">如果新点的父结点为红色，这时就需要进行一系列操作以保证整棵树红黑性质。如图</span>3<span style="font-family: 宋体; ">所示，由于父结点为红色，此时可以判定，祖父结点必定为黑色。这时需要根据叔父结点的颜色来决定做什么样的操作。青色结点表示颜色未知。由于有可能需要根结点到新点的路径上进行多次旋转操作，而每次进行不平衡判断的起始点（我们可将其视为新点）都不一样。所以我们在此使用一个蓝色箭头指向这个起始点，并称之为判定点。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb03-1.jpg" border="0" alt="" width="194" height="123" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 12pt; ">2.1&nbsp;</span></strong><strong><span style="font-family: 宋体; font-size: 12pt; ">红叔</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">当叔父结点为红色时，如图</span>4<span style="font-family: 宋体; ">所示，无需进行旋转操作，只要将父和叔结点变为黑色，将祖父结点变为红色即可。但由于祖父结点的父结点有可能为红色，从而违反红黑树性质。此时必须将祖父结点作为新的判定点继续向上进行平衡操作。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb04.jpg" border="0" alt="" width="308" height="123" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">需要注意，无论&#8220;父&#8221;在&#8220;叔&#8221;的左边还是右边，无论&#8220;新&#8221;是&#8220;父&#8221;的左孩子还是右孩子，它们的操作都完全一样。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 12pt; ">2.2&nbsp;</span></strong><strong><span style="font-family: 宋体; font-size: 12pt; ">黑叔</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">当叔父结点为黑色时，需要进行旋转，以下图示了所有的旋转可能</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>1<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb05.jpg" border="0" alt="" width="403" height="143" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>2<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb06.jpg" border="0" alt="" width="371" height="155" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /><br /><div><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>3<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb07.jpg" border="0" alt="" width="352" height="151" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>4<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb08.jpg" border="0" alt="" width="356" height="150" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">可以观察到，当旋转完成后，新的旋转根全部为黑色，此时不需要再向上回溯进行平衡操作，插入操作完成。需要注意，上面四张图的&#8220;叔&#8221;、&#8220;</span>1<span style="font-family: 宋体; ">&#8221;、&#8220;</span>2<span style="font-family: 宋体; ">&#8221;、&#8220;</span>3<span style="font-family: 宋体; ">&#8221;结点有可能为黑哨兵结点。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">其实红黑树的插入操作不是很难，甚至比</span>AVL<span style="font-family: 宋体; ">树的插入操作还更简单些。但删除操作就远远比</span>AVL<span style="font-family: 宋体; ">树复杂得多，下面就介绍红黑树的删除操作。</span></p><h3><a name="t6" style="color: rgb(255, 153, 0); text-decoration: none; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.cppblog.com/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat no-repeat; "></a><span style="font-family: 宋体; ">红黑树上结点的删除</span></h3><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">红黑树本身是一棵二叉查找树，它的删除和二叉查找树的删除类似。首先要找到真正的删除点，当被删除结点</span>n<span style="font-family: 宋体; ">存在左右孩子时，真正的删除点应该是</span>n<span style="font-family: 宋体; ">的中序遍在前驱，关于这一点请复习二叉查找树的删除。如图</span>9<span style="font-family: 宋体; ">所示，当删除结点</span>20<span style="font-family: 宋体; ">时，实际被删除的结点应该为</span>18<span style="font-family: 宋体; ">，结点</span>20<span style="font-family: 宋体; ">的数据变为</span>18<span style="font-family: 宋体; ">。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb09.jpg" border="0" alt="" width="243" height="152" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">所以可以推断出，在进行删除操作时，真正的删除点必定是只有一个孩子或没有孩子的结点。而根据红黑树的性质可以得出以下两个结论：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">1、&nbsp;<strong><span style="font-family: 宋体; ">删除操作中真正被删除的必定是只有一个红色孩子或没有孩子的结点</span></strong><span style="font-family: 宋体; ">。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">2、&nbsp;<strong><span style="font-family: 宋体; ">如果真正的删除点是一个红色结点，那么它必定是一个叶子结点</span></strong><span style="font-family: 宋体; ">。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">理解这两点非常重要，如图</span>10<span style="font-family: 宋体; ">所示，除了情况</span>(a)<span style="font-family: 宋体; ">外，其他任一种况结点</span>N<span style="font-family: 宋体; ">都无法满足红黑树性质。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb10.jpg" border="0" alt="" width="474" height="168" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">在以下讨论中，我们使用蓝色箭头表示真正的删除点，它也是旋转操作过程中的第一个判定点；真正的删除点使用&#8220;旧&#8221;标注，旧点所在位置将被它的的孩子结点所取代（最多只有一个孩子），我们使用&#8220;新&#8221;表示旧点的孩子结点。删除操作可分为以下几种情形：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 14pt; ">1</span></strong><strong><span style="font-family: 宋体; font-size: 14pt; ">、旧点为红色结点</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">若旧点为红色结点，则它必定是叶子结点，直接删除即可。如图</span>11<span style="font-family: 宋体; ">所示</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb11.jpg" border="0" alt="" width="253" height="101" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 14pt; ">2</span></strong><strong><span style="font-family: 宋体; font-size: 14pt; ">、一红一黑</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">当旧点为黑色结点，新点为红色结点时，将新点取代旧点位置后，将新点染成黑色即可（如图</span>12<span style="font-family: 宋体; ">所示）。这里需要注意：旧点为红色，新点为黑色的情况不可能存在。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb12.jpg" border="0" alt="" width="229" height="132" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 14pt; ">3</span></strong><strong><span style="font-family: 宋体; font-size: 14pt; ">、双黑</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">当旧点和新点都为黑色时（新点为空结点时，亦属于这种情况），情况比较复杂，需要根据旧点兄弟结点的颜色来决定进行什么样的操作。我们使用&#8220;兄&#8221;来表示旧点的兄弟结点。这里可分为红兄和黑兄两种情况：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 12pt; ">3.1&nbsp;</span></strong><strong><span style="font-family: 宋体; font-size: 12pt; ">红兄</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">由于兄弟结点为红色，所以父结点必定为黑色，而旧点被删除后，新点取代了它的位置。下图演示了两种可能的情况：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb13.jpg" border="0" alt="" width="359" height="246" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">红兄的情况需要进行</span>RR<span style="font-family: 宋体; ">或</span>LL<span style="font-family: 宋体; ">型旋转，然后将父结点染成红色，兄结点染成黑色。然后重新以新点为判定点进行平衡操作。我们可以观察到，旋转操作完成后，判定点没有向上回溯，而是降低了一层，此时变成了黑兄的情况。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong><span style="font-size: 12pt; ">3.2&nbsp;</span></strong><strong><span style="font-family: 宋体; font-size: 12pt; ">黑兄</span></strong><strong></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">黑兄的情况最为复杂，需要根据黑兄孩子结点（这里用&#8220;侄&#8221;表示）和父亲结点的颜色来决定做什么样的操作。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>3.2.1&nbsp;</strong><strong><span style="font-family: 宋体; ">黑兄二黑侄红父</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">如图</span>14<span style="font-family: 宋体; ">所示，这种情况比较简单，只需将父结点变为黑色，兄结点变为黑色，新结点变为黑色即可，删除操作到此结束。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb14.jpg" border="0" alt="" width="356" height="246" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>3.2.2&nbsp;</strong><strong><span style="font-family: 宋体; ">黑兄二黑侄黑父</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">如图</span>15<span style="font-family: 宋体; ">所示，此时将父结点染成新结点的颜色，新结点染成黑色，兄结点染成红色即可。当新结点为红色时，父结点被染成红色，此时需要以父结点为判定点继续向上进行平衡操作。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb15.jpg" border="0" alt="" width="362" height="248" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /><br /><div><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><strong>3.2.3&nbsp;</strong><strong><span style="font-family: 宋体; ">黑兄红侄</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">黑兄红侄有以下四种情形，下面分别进行图示：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>1<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb16.jpg" border="0" alt="" width="394" height="144" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>2<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb17.jpg" border="0" alt="" width="370" height="153" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>3<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://pic002.cnblogs.com/img/abatei/200904/2009042421464472.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">情形</span>4<span style="font-family: 宋体; ">：</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img src="http://images.cnblogs.com/cnblogs_com/abatei/rb19.jpg" border="0" alt="" width="379" height="151" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; " /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="font-family: 宋体; ">由以上图例所示，看完以上四张图的兄弟有可能会有一个疑问，如果情形</span>1<span style="font-family: 宋体; ">和情形</span>2<span style="font-family: 宋体; ">中的两个侄子结点都为红色时，是该进行</span>LL<span style="font-family: 宋体; ">旋转还是进行</span>LR<span style="font-family: 宋体; ">旋转呢？答案是进行</span>LL<span style="font-family: 宋体; ">旋转。情形</span>3<span style="font-family: 宋体; ">和情形</span>4<span style="font-family: 宋体; ">则是优先进行</span>RR<span style="font-family: 宋体; ">旋转的判定。<br /><div><span style="font-family: Arial; "><h2><span style="font-family: 黑体; ">红黑树的代码实现</span></h2></span></div></span></p></div></p></div></p></span></div></span></font><img src ="http://www.cppblog.com/mysileng/aggbug/191149.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-09-18 20:32 <a href="http://www.cppblog.com/mysileng/archive/2012/09/18/191149.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>