﻿<?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++博客-每天多学习1个小时-随笔分类-Algorithm</title><link>http://www.cppblog.com/hello8706/category/15128.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 29 Oct 2010 04:35:57 GMT</lastBuildDate><pubDate>Fri, 29 Oct 2010 04:35:57 GMT</pubDate><ttl>60</ttl><item><title>线段树特辑（一，相关理论）</title><link>http://www.cppblog.com/hello8706/archive/2010/10/25/131164.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Mon, 25 Oct 2010 08:28:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/10/25/131164.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/131164.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/10/25/131164.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/131164.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/131164.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 无意间在网上看到了线段树，并且对此引发的讨论也是络绎不绝呀~所以自己也对这个感兴趣起来。目前对线段树的应用领域，我可以说是完全不理解的，不过相信这个特辑做完了过后，我就能有初步的理解了，特辑包含理论以及一些关于线段树的题。OK，废话不说，先复制个理论上来。其实理论看起来还是蛮好理解的，不过实践才是王道。在一类问题中,我们需要经常处理可以映射在一个坐标轴上的一些固定线段,例如说映射在OX轴上的线...&nbsp;&nbsp;<a href='http://www.cppblog.com/hello8706/archive/2010/10/25/131164.html'>阅读全文</a><img src ="http://www.cppblog.com/hello8706/aggbug/131164.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-10-25 16:28 <a href="http://www.cppblog.com/hello8706/archive/2010/10/25/131164.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>直接插入排序法</title><link>http://www.cppblog.com/hello8706/archive/2010/10/09/129232.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Sat, 09 Oct 2010 10:20:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/10/09/129232.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/129232.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/10/09/129232.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/129232.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/129232.html</trackback:ping><description><![CDATA[<p>开始研究算法导论，第一个就是直接排序算法，可是看书太慢了。<br>所以开始寻找这个的道路。索性找到啦~一边贴上。一边用代码实现，再复制到自己的博客上，学海无涯啊~<br></p>
插入排序(Insertion Sort)的基本思想是：每次将一个待排序的记录，按其关键字大小插入到前面已经排好序的子文件中的适当位置，直到全部记录插入完成为止。<br><strong><font size=4>直接插入排序基本思想<br><br></font>1、基本思想<br></strong>&nbsp;&nbsp;&nbsp; 　假设待排序的记录存放在数组R[1..n]中。初始时，R[1]自成1个有序区，无序区为R[2..n]。从i=2起直至i=n为止，依次将R[i]插入当前的有序区R[1..i-1]中，生成含n个记录的有序区。<br><br><strong>2、第i-1趟直接插入排序：</strong><br>&nbsp;&nbsp;&nbsp; 　通常将一个记录R[i](i=2，3，&#8230;，n-1)插入到当前的有序区，使得插入后仍保证该区间里的记录是按关键字有序的操作称第i-1趟直接插入排序。<br>&nbsp;&nbsp;&nbsp; 　排序过程的某一中间时刻，R被划分成两个子区间R[1．．i-1]（已排好序的有序区）和R[i．．n]（当前未排序的部分，可称无序区）。<br>&nbsp;&nbsp;&nbsp; 　直接插入排序的基本操作是将当前无序区的第1个记录R[i]插人到有序区R[1．．i-1]中适当的位置上，使R[1．．i]变为新的有序区。因为这种方法每次使有序区增加1个记录，通常称增量法。<br>&nbsp;&nbsp;&nbsp; 　插入排序与打扑克时整理手上的牌非常类似。摸来的第1张牌无须整理，此后每次从桌上的牌(无序区)中摸最上面的1张并插入左手的牌(有序区)中正确的位置上。为了找到这个正确的位置，须自左向右(或自右向左)将摸来的牌与左手中已有的牌逐一比较。<br><strong><font size=4>一趟直接插入排序方法<br><br></font>1．简单方法<br></strong>&nbsp;&nbsp;&nbsp; 　首先在当前有序区R[1..i-1]中查找R[i]的正确插入位置k(1&#8804;k&#8804;i-1)；然后将R[k．．i-1]中的记录均后移一个位置，腾出k位置上的空间插入R[i]。<br>&nbsp; <font color=#ff0000>注意：</font><br>&nbsp;&nbsp;&nbsp; 　若R[i]的关键字大于等于R[1．．i-1]中所有记录的关键字，则R[i]就是插入原位置。<br><font color=#ff0000><br></font><strong>2．改进的方法</strong><br>　　一种查找比较操作和记录移动操作交替地进行的方法。<br>具体做法：<br>&nbsp;&nbsp;&nbsp; 　将待插入记录R[i]的关键字从右向左依次与有序区中记录R[j](j=i-1，i-2，&#8230;，1)的关键字进行比较：<br>&nbsp;&nbsp;&nbsp; 　① 若R[j]的关键字大于R[i]的关键字，则将R[j]后移一个位置；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ②若R[j]的关键字小于或等于R[i]的关键字，则查找过程结束，j+1即为R[i]的插入位置。<br>&nbsp;&nbsp;&nbsp; 　关键字比R[i]的关键字大的记录均已后移，所以j+1的位置已经腾空，只要将R[i]直接插入此位置即可完成一趟直接插入排序。<br><br><strong><font size=4>直接插入排序算法<br></font><br>1．算法描述（伪代码）<br></strong><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;lnsertSort(SeqList&nbsp;R)<br>&nbsp;&nbsp;&nbsp;{&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">对顺序表R中的记录R[1..n]按递增序进行插入排序</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i，j；<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">n；i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">依次插入R[2]，&#8230;，R[n]</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(R[i].key</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">R[i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">].key){</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">若R[i].key大于等于有序区中所有的keys，则R[i]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">应在原有位置上</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">R[i];j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">R[0]是哨兵，且是R[i]的副本</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">{&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">从右向左在有序区R[1．．i-1]中查找R[i]的插入位置</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">R[j]；&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">将关键字大于R[i].key的记录后移</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">&nbsp;；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(R[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">].key</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">R[j].key)；&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">当R[i].key&#8805;R[j].key时终止</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">R[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]；&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">R[i]插入到正确的位置上</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">endif</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">InsertSort</span></div>
<br><strong>2．哨兵的作用<br></strong>&nbsp;&nbsp;&nbsp; 　算法中引进的附加记录R[0]称监视哨或哨兵(Sentinel)。<br>&nbsp;&nbsp;&nbsp;　 哨兵有两个作用：<br>　　① 进人查找(插入位置)循环之前，它保存了R[i]的副本，使不致于因记录后移而丢失R[i]的内容；<br>　　② 它的主要作用是：在查找循环中"监视"下标变量j是否越界。一旦越界(即j=0)，因为R[0].key和自己比较，循环判定条件不成立使得查找循环结束，从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件"j&gt;=1")。<br>&nbsp; <font color=#ff0000>注意：</font><br>　&nbsp; ① 实际上，一切为简化边界条件而引入的附加结点(元素)均可称为哨兵。<br>　　&nbsp; 【例】单链表中的头结点实际上是一个哨兵<br>　　② 引入哨兵后使得测试查找循环条件的时间大约减少了一半，所以对于记录数较大的文件节约的时间就相当可观。对于类似于排序这样使用频率非常高的算法，要尽可能地减少其运行时间。所以不能把上述算法中的哨兵视为雕虫小技，而应该深刻理解并掌握这种技巧。<br><br><strong><font size=4>给定输入实例的排序过程</font></strong><br><br>&nbsp;&nbsp;&nbsp; 　设待排序的文件有8个记录，其关键字分别为：49，38，65，97，76，13，27，<u>49</u>。为了区别两个相同的关键字49，后一个49的下方加了一下划线以示区别。其排序过程见【&nbsp;&nbsp;动画演示&nbsp; <a href="http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/insertsort.htm">http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/insertsort.htm</a>】<br><br><strong><font size=4>算法分析<br></font><br>1．算法的时间性能分析&nbsp;</strong><br>&nbsp;&nbsp;&nbsp; 　对于具有n个记录的文件，要进行n-1趟排序。<br>&nbsp;&nbsp;&nbsp; 各种状态下的时间复杂度：<br><br>初始文件状态&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;正序&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;反序&nbsp;&nbsp;&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;<br>第i趟的关键&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（i-2）/2<br>字比较次数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>总关键字比较次数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(n+2)(n-1)/2&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;≈n<sup>2</sup>/4&nbsp;<br>第i趟记录移动次数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（i-2）/2&nbsp; <br>总的记录移动次数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(n-1)(n+4)/2&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;≈n<sup>2</sup>/4&nbsp;<br>时间复杂度&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0（n）&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;O（n<sup>2</sup>）&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; O（n<sup>2</sup>）<br><br><font color=#ff0000>注意：</font><br>&nbsp;&nbsp;&nbsp; 　初始文件按关键字递增有序，简称"正序"。<br>　&nbsp;&nbsp;&nbsp; 初始文件按关键字递减有序，简称"反序"。 <br><font color=#ff0000><br></font><strong>2．算法的空间复杂度分析</strong><br>&nbsp;&nbsp;&nbsp; 　算法所需的辅助空间是一个监视哨，辅助空间复杂度S(n)=O(1)。是一个就地排序。<br><br><strong>3．直接插入排序的稳定性</strong><br>&nbsp;&nbsp;&nbsp; 　直接插入排序是稳定的排序方法。 <br><br>个人实现的C++代码也贴上：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008000">//</span><span style="COLOR: #008000">假设是降序排列</span><span style="COLOR: #008000"><br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;InsertSort(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;nArray,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;size)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nSentinel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">哨兵,用来保存nArray[i]的副本</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;size;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(nArray[i]&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;nArray[i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nSentinel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;nArray[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&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;nArray[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;&nbsp;nArray[j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(nSentinel&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;nArray[j]&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nArray[j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;nSentinel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;temp[]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">33</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">25</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">25</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">33</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">55</span><span style="COLOR: #000000">};<br>&nbsp;&nbsp;&nbsp;&nbsp;InsertSort(temp,</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;temp[i]&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;getchar();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div>
<br>直接插入排序法，针对少量的数据项排序，速度比较快，数据越大，这中方法的劣势也就越明显了。 
<img src ="http://www.cppblog.com/hello8706/aggbug/129232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-10-09 18:20 <a href="http://www.cppblog.com/hello8706/archive/2010/10/09/129232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>红黑树研究之二(转C#与数据结构－树论—红黑树)</title><link>http://www.cppblog.com/hello8706/archive/2010/10/08/129038.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Fri, 08 Oct 2010 05:39:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/10/08/129038.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/129038.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/10/08/129038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/129038.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/129038.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 红黑树的平衡红黑树首先是一棵二叉查找树，它每个结点都被标上了颜色（红色或黑色），红黑树满足以下5个性质：1、 每个结点的颜色只能是红色或黑色。2、 根结点是黑色的。3、 每个叶子结点都带有两个空的黑色结点（被称为黑哨兵），如果一个结点n的只有一个左孩子，那么n的右孩子是一个黑哨兵；如果结点n只有一个右孩子，那么n的左孩子是一个黑哨兵。4、 如果一个结点是红的，则它的两个儿子都是...&nbsp;&nbsp;<a href='http://www.cppblog.com/hello8706/archive/2010/10/08/129038.html'>阅读全文</a><img src ="http://www.cppblog.com/hello8706/aggbug/129038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-10-08 13:39 <a href="http://www.cppblog.com/hello8706/archive/2010/10/08/129038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>红黑树研究之一</title><link>http://www.cppblog.com/hello8706/archive/2010/10/08/129022.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Fri, 08 Oct 2010 03:12:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/10/08/129022.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/129022.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/10/08/129022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/129022.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/129022.html</trackback:ping><description><![CDATA[这几天又开始研究新的排序算法，红黑树。工作需要，那就顺便学习了~<br><br>
<p>前言： </p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 之所以要写这篇文章，第一个目的是为了各位朋友在查看我写的源代码之前有一个可以理解理论的文章因为红黑树还是有点难的，</span><span style="FONT-SIZE: 10.5pt">如果不想搞懂理论，而直接看代码，那绝对是云里雾里，不知所云。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第二个目的是我觉得网上虽然后不少我文章也在讲，但是我就是理解</span><span style="FONT-SIZE: 10.5pt">不上有点困难，在我参考了很多文章之后，认真阅读才慢慢摸透了其中的原理，所以我想用自己的方式来表达，希望有助于各位的朋友理</span><span style="FONT-SIZE: 10.5pt">解。<br><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; TEXT-INDENT: 0.95pt"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">红黑树由来：</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -23pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 23pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 他是在1972年 由</span><span style="FONT-SIZE: 10.5pt">Rudolf Bayer</span><span style="FONT-SIZE: 10.5pt">发明的，他称之为&#8220;对称二叉B树&#8221;，它现代的名字是</span><span style="FONT-SIZE: 10.5pt">Leo J. Guibas</span><span style="FONT-SIZE: 10.5pt">和 </span><span style="FONT-SIZE: 10.5pt">Robert Sedgewick </span><span style="FONT-SIZE: 10.5pt">于</span><span style="FONT-SIZE: 10.5pt">1978</span><span style="FONT-SIZE: 10.5pt">年写的一篇论文中获得的。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;它是复杂的，但它的操作有着良好的最坏情况运行时间，并且在实践中是高效的<span style="FONT-FAMILY: Lucida Sans">: </span></span><span style="FONT-SIZE: 10.5pt">它可以在</span><span style="FONT-SIZE: 10.5pt">O(log n)</span><span style="FONT-SIZE: 10.5pt">时间内做查找，</span><span style="FONT-SIZE: 10.5pt">插入和删除，这里的</span><span style="FONT-SIZE: 10.5pt">n</span><span style="FONT-SIZE: 10.5pt"> 是树中元素的数目。<br><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; TEXT-INDENT: 0.95pt"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">红黑树性质</span><span style="FONT-SIZE: 10.5pt">：</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">1. </span><span style="FONT-SIZE: 10.5pt">每个结点或红或黑。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">2. </span><span style="FONT-SIZE: 10.5pt">根结点为黑色。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">3. </span><span style="FONT-SIZE: 10.5pt">每个叶结点</span><span style="FONT-SIZE: 10.5pt">(</span><span style="FONT-SIZE: 10.5pt">实际上就是</span><span style="FONT-SIZE: 10.5pt">NULL</span><span style="FONT-SIZE: 10.5pt">指针</span><span style="FONT-SIZE: 10.5pt">)</span><span style="FONT-SIZE: 10.5pt">都是黑色的。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">4. </span><span style="FONT-SIZE: 10.5pt">如果一个结点是红色的<span style="FONT-FAMILY: Lucida Sans">,</span></span><span style="FONT-SIZE: 10.5pt">那么它的周边</span><span style="FONT-SIZE: 10.5pt">3</span><span style="FONT-SIZE: 10.5pt">个节点都是黑色的。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">5. </span><span style="FONT-SIZE: 10.5pt">对于每个结点<span style="FONT-FAMILY: Lucida Sans">,</span></span><span style="FONT-SIZE: 10.5pt">从该结点到其所有子孙叶结点的路径中所包含的黑色结点个数都一样。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; TEXT-INDENT: 0.95pt"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">讨论的前提：</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">1</span><span style="FONT-SIZE: 10.5pt">，</span><span style="FONT-SIZE: 10.5pt">我们只讨论往树的左边和从树的左边删除的情况，与之对称的情况一样。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">2</span><span style="FONT-SIZE: 10.5pt">，</span><span style="FONT-SIZE: 10.5pt">假设我们要删除一个元素的方法都是采取删除后继节点，而非前驱节点。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">3</span><span style="FONT-SIZE: 10.5pt">，</span><span style="FONT-SIZE: 10.5pt">NL</span><span style="FONT-SIZE: 10.5pt">或全黑表示黑空节点，也可以不用画出。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">4</span><span style="FONT-SIZE: 10.5pt">，</span><span style="FONT-SIZE: 10.5pt">&#8220;<span style="FONT-FAMILY: Times New Roman">=&gt;</span><span style="FONT-FAMILY: Lucida Sans">&#8221;</span></span><span style="FONT-SIZE: 10.5pt">这个符号我们用来表示<span style="FONT-FAMILY: Lucida Sans">&#8220;</span><span style="FONT-FAMILY: 宋体">变成</span><span style="FONT-FAMILY: Lucida Sans">&#8221;</span><span style="FONT-FAMILY: 宋体">的意思。</span></span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">一． </span><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">插入</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">当红黑树中没有节点的时候，新节点直接涂黑就可以了。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">当树中已有节点，我们就将新节点涂红，并且底下挂两个黑空节点。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640532460-0.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">1.1 </span><span style="FONT-SIZE: 10.5pt">新节点的父亲为黑色</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">这种情况最简单，只接插入将新节点可以了，不会出现红色警戒。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/16405360a-1.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">1.2 </span><span style="FONT-SIZE: 10.5pt">新节点的父亲为红色</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">这种情况出现红色警戒，并且通过红色的父亲，我们可以推出一定有一个黑色的父，</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">并且父亲不可能为树根</span><span style="FONT-SIZE: 10.5pt">(</span><span style="FONT-SIZE: 10.5pt">树根必须为黑</span><span style="FONT-SIZE: 10.5pt">)</span><span style="FONT-SIZE: 10.5pt">。</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640536343-2.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">这种情况需要修复。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">1.2.1 </span><span style="FONT-SIZE: 10.5pt">新节点的叔叔是红色。（红叔）</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify" align=center><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/164053O17-3.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" align=left><span style="FONT-SIZE: 10.5pt">图</span><span style="FONT-SIZE: 10.5pt">1.2.1-1</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 150%; TEXT-ALIGN: justify" align=left><span style="FONT-SIZE: 10.5pt"><span style="FONT-FAMILY: 宋体"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640532551-4.jpg" border=0 small="0"></span><br></span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" align=left><span style="FONT-SIZE: 10.5pt">图</span><span style="FONT-SIZE: 10.5pt">1.2.1-2</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 21pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 21pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">注解：在这种情况下，我们可以通过这样的方式来修复红黑树的性质。因为遇到红</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">色警戒所以我们首先可以想到的就是将父亲变成黑色，但这样祖父的左子树的黑高</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">就增加了，为了达到祖父的平衡，我们红叔变成黑色，这样祖父就平衡了。但是整</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">个祖父这颗树的高度增高了，所以再此将祖父的颜色变成红色来保持祖父这颗树的</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">高度不变。因为祖父变成了红色，因此往上遍历。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法：父<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑；叔</span><span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑；祖</span><span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">红；往上遍历；</span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">1.2.2 </span><span style="FONT-SIZE: 10.5pt">新节点的叔叔是黑色（黑叔）</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640535V0-5.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">图</span><span style="FONT-SIZE: 10.5pt">1.2.2-1</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/164053AF-6.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">图</span><span style="FONT-SIZE: 10.5pt">1.2.2-2</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 21pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 21pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">注解：首先可以说明的是，这种情况下我们都可以通过改变颜色和旋转的方式到达</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">平衡，并且不再出现红色警戒，因为无需往上遍历。图</span><span style="FONT-SIZE: 10.5pt">1.2.2-1<span style="FONT-FAMILY: 永中宋体">：</span></span><span style="FONT-SIZE: 10.5pt">首先我们将红父变</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">成黑色，祖父变成红色，然后对祖父进行右旋转。这样我们可以看到，整颗树的黑</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">高不变，并且这颗树的左右子树也达到平衡。新的树根为黑色。因此无需往上遍历。</span><span style="FONT-SIZE: 10.5pt"><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 21pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 21pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">方法：图</span><span style="FONT-SIZE: 10.5pt">1.2.2-1&nbsp;&nbsp;</span><span style="FONT-SIZE: 10.5pt">父<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑；祖</span><span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">红；祖父右旋转；</span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">图</span><span style="FONT-SIZE: 10.5pt">1.2.2-2</span><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp; 新<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑；祖</span><span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">红；父左旋转；祖右旋转；</span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt"><span style="FONT-FAMILY: 永中宋体"><br></span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">插入我们就算做完了，与之对称的右边插入的情况完全一样，请自己下来分析；</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">一． </span><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">删除</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 22.995pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">删除是比较经典但也是最困难的一件事了，所以我们必须一步一步地理解。为了中途思想不混乱，请始终记住一点，下面我们删除的节点都已经表示的是实际要删除的后继节点了。因此可以得出一下结论。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 10.5pt; COLOR: #0000ff">首先</span><span style="FONT-SIZE: 10.5pt">，可以肯定的是我们要删除的节点</span><span style="FONT-SIZE: 10.5pt; COLOR: #0000ff">要么是红色</span><span style="FONT-SIZE: 10.5pt">，</span><span style="FONT-SIZE: 10.5pt; COLOR: #0000ff">要么是黑色。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt; COLOR: #0000ff">其次</span><span style="FONT-SIZE: 10.5pt">，既然我们要删除的结点是后继节点，那么要删除的节点的左子树一定为空。所以当删除的节点为黑色时只剩下两种情况。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt; COLOR: #0000ff">最后</span><span style="FONT-SIZE: 10.5pt">，如果删除的节点为红色，那么它必为叶子节点。<span style="FONT-FAMILY: Lucida Sans">(</span></span><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">自己好好想象为什么</span><span style="FONT-SIZE: 10.5pt">)<span style="FONT-FAMILY: 永中宋体">。</span></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">请在看下面的内容前先牢记上面的结论，这样更加方便让你理解下面的知识。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">a<span style="FONT-FAMILY: 永中宋体">：</span></span><span style="FONT-SIZE: 10.5pt">当删除的节点为黑色时</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg height=134 src="http://www.cc616.com/uploads/allimg/100906/164053N19-7.jpg" width=268 border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删黑</span><span style="FONT-SIZE: 10.5pt">a </span><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删黑#p#分页标题#e#</span><span style="FONT-SIZE: 10.5pt">b</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt"><br></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">b<span style="FONT-FAMILY: 永中宋体">：</span></span><span style="FONT-SIZE: 10.5pt">当删除的节点为红色时</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640533G8-8.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">上面的几附图都是很简单的。因为你可以将空节点</span><span style="FONT-SIZE: 10.5pt"> <span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640535163-9.jpg" border=0 small="0"></span>去掉不看。所就形成了要</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">删除的节点要么有一个右孩子，要么为叶子节点。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt"><br></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">下面我们就开始真正的删除操作了。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">2.1 </span><span style="FONT-SIZE: 10.5pt">删除红色节点</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640533230-10.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 21pt; LINE-HEIGHT: 120%; MARGIN-RIGHT: -4.62pt; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">注解：这种情况是最简单的，因为根据</span><span><span style="FONT-SIZE: 10pt; COLOR: #0000ff; TEXT-DECORATION: underline">上面的结论</span></span><span style="FONT-SIZE: 10.5pt">我们可以推出子节点&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">一定为空，</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">也就是说删除的红色节点为叶子节点。只需将这个旧节点的右孩子付给父亲的左孩子就</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">可以了，高度不变。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">方法：</span><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">略</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic"><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">2.2 </span><span style="FONT-SIZE: 10.5pt">删除黑色节点</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">遇到黑色节点情况就将变得复杂起来，因此我们一定要慢慢来，仔细分析。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">2.2.1</span><span style="FONT-SIZE: 10.5pt">当删除的节点有一个红色子孩子</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640534600-11.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 20.055pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 22.995pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">注解：这种情况其实就是上面我们分析的三种情况之一，如图</span><span style="FONT-SIZE: 10.5pt">"</span><span><span style="FONT-SIZE: 10pt; COLOR: #0000ff; TEXT-DECORATION: underline">删黑b</span></span><span style="FONT-SIZE: 10.5pt">"</span><span style="FONT-SIZE: 10.5pt">。这种情况</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">是非常简单的，只需将旧节点的右孩子取代旧节点，并将子孩子的颜色变为黑色，</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">树平衡；</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法：子取代旧；子<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑；</span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 20.055pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 22.995pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">2.2.2</span><span style="FONT-SIZE: 10.5pt">当删除的节点无左右孩子</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">这种情况其实就是上面我们分析的三种情况之一，如图</span><span style="FONT-SIZE: 10.5pt">"</span><span style="FONT-SIZE: 10.5pt">删黑</span><span style="FONT-SIZE: 10.5pt">a"</span><span style="FONT-SIZE: 10.5pt">。我们推出子</span><span style="FONT-SIZE: 10.5pt">节点</span><span style="FONT-SIZE: 10.5pt"> <span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/16405344O-12.jpg" border=0 small="0"></span></span><span style="FONT-SIZE: 10.5pt">一定为空，请务必记住这点，不然在后面你将很容易被混淆，父亲的颜</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">色我们标记为绿色，是表示，父亲的颜色可为红或黑。黄色的子节点<span><span><img class=blogimg height=33 src="http://www.cc616.com/uploads/allimg/100906/16405362X-13.jpg" width=35 border=0 small="0"></span></span>其实就</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">是一个黑空节点，这样方便后面分析。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640532317-14.jpg" border=0 small="0"></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt">&nbsp;</p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">a</span><span style="FONT-SIZE: 10.5pt">：红兄</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/164053I61-15.jpg" border=0 small="0"></span><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 21pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 21pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">注解：当我们删除的节点拥有一个红色的兄弟时，这种情况还相对比较简单，因为</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">兄弟为黑色，我们可以推出父亲一定为黑色。因为父节点的左树高度减一，所</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">以我们可以通过左旋转父节点，来将节点</span><span style="FONT-SIZE: 10.5pt">1</span><span style="FONT-SIZE: 10.5pt">旋转到左边来恢复左边的高度。然</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">后将父变成</span><span style="FONT-SIZE: 10.5pt">红</span><span style="FONT-SIZE: 10.5pt">，兄变成黑。这样整颗树的高度不变，父节点也平衡记住子</span><span style="FONT-SIZE: 10.5pt">节点 </span><span style="FONT-SIZE: 10.5pt"><span><span><img class=blogimg height=33 src="http://www.cc616.com/uploads/allimg/100906/16405362X-13.jpg" width=35 border=0 small="0"></span></span></span><span style="FONT-SIZE: 10.5pt">为空所以可以删除看，这样便于理解。其实我们也可以推出</span><span style="FONT-SIZE: 10.5pt">1<span style="FONT-FAMILY: 永中宋体">，</span><span style="FONT-FAMILY: Times New Roman">2</span></span><span style="FONT-SIZE: 10.5pt">为空，但这</span><span style="FONT-SIZE: 10.5pt">里没有必要。</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法：父<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">红；兄</span><span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑；左旋转父节点；<br><br></span></span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">b </span><span style="FONT-SIZE: 10.5pt">：黑兄</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">遇到黑兄就又麻烦了，我们又必须引入要删除的节点的侄子了。所以我们这里</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">再次细分为</span><span style="FONT-SIZE: 10.5pt">b1: </span><span style="FONT-SIZE: 10.5pt">黑兄 双黑侄 </span><span style="FONT-SIZE: 10.5pt">b2:</span><span style="FONT-SIZE: 10.5pt"> 黑兄 左黑侄右红侄</span><span style="FONT-SIZE: 10.5pt"> b3: </span><span style="FONT-SIZE: 10.5pt">黑兄 右黑侄左红侄。</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">可能你会问</span><span style="FONT-SIZE: 10.5pt">b4</span><span style="FONT-SIZE: 10.5pt">呢，双红侄的情况呢？其实双红侄的情况同属于</span><span style="FONT-SIZE: 10.5pt">b2,b3</span><span style="FONT-SIZE: 10.5pt">的情况，所以</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">可以默认用</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">b2,b3</span><span style="FONT-SIZE: 10.5pt">其中一种情况来处理就可以了。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt -0.945pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.945pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt; FONT-STYLE: italic">现在我们开始了</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">b1</span><span style="FONT-SIZE: 10.5pt">黑兄 双黑侄</span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/1640535062-17.jpg" border=0 small="0"></span><br><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 21pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 21pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">注解：我们首先可以肯定的是父节点的左子树高度减一了，所以我们必须想方设法</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">来弥补这个缺陷</span><span style="FONT-SIZE: 10.5pt">。</span><span style="FONT-SIZE: 10.5pt">如果我们把父节点的右子树高度也减一（兄变成红色）那么</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">父节点这颗树就可以保持平衡了，但整颗树的高度减一，所以我们可以判断，</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">如果父亲是红色，那么我们可以通过把父亲变成黑色来弥补这一缺陷。但如果</span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">父亲是黑色呢，既然遇到到黑色了我们就只好往上遍历了。</span></p>
<p class=p0 style="MARGIN: 0pt -4.62pt 0pt 20.055pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 22.995pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">方法：兄<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">红；子</span><span style="FONT-FAMILY: Lucida Sans">=</span><span style="FONT-FAMILY: 永中宋体">黑；&nbsp;&nbsp;&nbsp;</span></span><span style="FONT-SIZE: 10.5pt"> </span><span style="FONT-SIZE: 10.5pt">红父<span style="FONT-FAMILY: Lucida Sans">=&gt;</span><span style="FONT-FAMILY: 永中宋体">黑</span><span style="FONT-FAMILY: Lucida Sans">;</span></span></p>
<p class=p0 style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt"><span style="FONT-SIZE: 10.5pt">&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;</span><span style="FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="FONT-SIZE: 10.5pt">往上遍历</span><span style="FONT-SIZE: 10.5pt">(</span><span style="FONT-SIZE: 10.5pt">黑父</span><span style="FONT-SIZE: 10.5pt">)</span><span style="FONT-SIZE: 10.5pt">;</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p>补充：其实子节点就是空节点，没有必要变。就算遍历上去，父节点也为黑<br><br></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">b2黑兄 左黑侄右红侄</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/16405354T-18.jpg" border=0 small="0"></span><br>注解：绿色表示，颜色不影响修复的方式。依然我们可以肯定父节点的左子树高度减一，所以我们可以通过将父节点旋转下来并且变为黑色来弥补，但由于兄弟被旋转上去了，又导致右子树高度减一，但我们这有一个红侄，所以可以通过红侄变成黑色来弥补。父亲所在位置的颜色不变；(<span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/164053F91-19.jpg" border=0 small="0"></span>子为空)<br>方法：兄=&gt;父色；父=&gt;黑；侄=&gt;黑；(子=&gt;黑)；左旋转父节点；<br><br>b3 黑兄 左红侄右黑侄</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/164053B28-20.jpg" border=0 small="0"></span><br>注解：绿色表示，颜色不影响修复的方式。依然我们可以肯定父节点的左子树高度减一,同样我们通过父节点左旋转到左子树来弥补这一缺陷。但如果直接旋转的话，我们可以推出左右子树将不平衡(黑父)，或者两个红色节点相遇(红父)；这样将会更加的复杂，甚至不可行。因此，我们考虑首先将兄弟所在子树右旋转，然后再左旋转父子树。这样我们就可以得到旋转后的树。然后通过修改颜色来使其达到平衡，且高度不变。<br>方法：侄=&gt;父色；父=&gt;黑;右旋转兄；左旋转父；</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt"><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">总结：</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">如果我们通过上面的情况画出所有的分支图，我们可以得出如下结论</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">插入操作：解决的是 红<span style="FONT-FAMILY: Lucida Sans">-</span></span><span style="FONT-SIZE: 10.5pt">红 问题</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">删除操作：解决的是 黑<span style="FONT-FAMILY: Lucida Sans">-</span></span><span style="FONT-SIZE: 10.5pt">黑 问题</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -23pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 23pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt">即你可以从分支图中看出，需要</span><span style="FONT-SIZE: 10.5pt">往</span><span style="FONT-SIZE: 10.5pt">上遍历的情况为红红</span><span style="FONT-SIZE: 10.5pt">(</span><span style="FONT-SIZE: 10.5pt">插入</span><span style="FONT-SIZE: 10.5pt">)</span><span style="FONT-SIZE: 10.5pt">；</span><span style="FONT-SIZE: 10.5pt">或者为黑黑黑（删除）的情况，，如果你认真分析并总结所有的情况后，并坚持下来，红黑树也就没有想象中的那么恐怖了，并且很美妙；</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -23pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 23pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-SIZE: 10.5pt"><br></span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; TEXT-INDENT: 0.95pt">&nbsp;</p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; TEXT-INDENT: 0.95pt"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">程序样列：</span></p>
<p class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; TEXT-INDENT: 0.95pt"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt"><span><img class=blogimg src="http://www.cc616.com/uploads/allimg/100906/164053FE-21.jpg" border=0 small="0"></span></span></p>
<h5>&#222; 通过做某些颜色修改并对p[x]做一次左旋，可以去掉x的额外黑色来把它变成单独黑色，而不破坏红黑性质。将x置为根后，当while循环测试其循环条件时循环结束。<br></h5>
<h5>&nbsp;</h5>
<h5 class=p0 style="MARGIN: 0pt -4.6pt 0pt -0.95pt; VERTICAL-ALIGN: baseline; TEXT-INDENT: 0.95pt; LINE-HEIGHT: 120%; TEXT-ALIGN: justify"><span style="FONT-WEIGHT: bold; FONT-SIZE: 10.5pt">参考文献：</span><br>博客园</h5>
<h5>&nbsp;&nbsp;&nbsp;<a href="http://www.cnblogs.com/">http://www.cnblogs.com</a></h5>
<h5>&nbsp;&nbsp; <a href="http://www.cnblogs.com/abatei/archive/2008/12/17/1356565.html">http://www.cnblogs.com/abatei/archive/2008/12/17/1356565.html</a></h5>
<h5><a href="http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html">&nbsp;&nbsp;&nbsp;http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html</a><br></h5>
<img src ="http://www.cppblog.com/hello8706/aggbug/129022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-10-08 11:12 <a href="http://www.cppblog.com/hello8706/archive/2010/10/08/129022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多串匹配-AC自动机</title><link>http://www.cppblog.com/hello8706/archive/2010/10/08/129020.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Fri, 08 Oct 2010 02:52:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/10/08/129020.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/129020.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/10/08/129020.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/129020.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/129020.html</trackback:ping><description><![CDATA[<p><strong><font color=#02368d size=5></font></strong>&nbsp;&nbsp;&nbsp;&nbsp;首先简要介绍一下<span>AC</span><span>自动机：</span><span>Aho-Corasick automation</span><span>，该算法在</span><span>1975</span><span>年产生于贝尔实验室，是著名的多模匹配算法之一。一个常见的例子就是给出</span><span>n</span><span>个单词，再给出一段包含</span><span>m</span><span>个字符的文章，让你找出有多少个单词在文章里出现过。要搞懂</span><span>AC</span><span>自动机，先得有模式树（字典树）</span><span>Trie</span><span>和</span><span>KMP</span><span>模式匹配算法的基础知识。</span><span>AC</span><span>自动机算法分为</span><span>3</span><span>步：构造一棵</span><span>Trie</span><span>树，构造失败指针和模式匹配过程。<br><span>&nbsp;&nbsp;&nbsp; 如果你对</span><span>KMP</span><span>算法和了解的话，应该知道</span><span>KMP</span><span>算法中的</span><span>next</span><span>函数（</span><span>shift</span><span>函数或者</span><span>fail</span><span>函数）是干什么用的。</span><span>KMP</span><span>中我们用两个指针</span><span>i</span><span>和</span><span>j</span><span>分别表示，</span><span>A[i-j+ 1..i]</span><span>与</span><span>B[1..j]</span><span>完全相等。也就是说，</span><span>i</span><span>是不断增加的，随着</span><span>i</span><span>的增加</span><span>j</span><span>相应地变化，且</span><span>j</span><span>满足以</span><span>A[i]</span><span>结尾的长度为</span><span>j</span><span>的字符串正好匹配</span><span>B</span><span>串的前</span><span> j</span><span>个字符，当</span><span>A[i+1]</span><span>&#8800;</span><span>B[j+1]</span><span>，</span><span>KMP</span><span>的策略是调整</span><span>j</span><span>的位置（减小</span><span>j</span><span>值）使得</span><span>A[i-j+1..i]</span><span>与</span><span>B[1..j]</span><span>保持匹配且新的</span><span>B[j+1]</span><span>恰好与</span><span>A[i+1]</span><span>匹配，而</span><span>next</span><span>函数恰恰记录了这个</span><span>j</span><span>应该调整到的位置。同样</span><span>AC</span><span>自动机的失败指针具有同样的功能，也就是说当我们的模式串在</span><span>Tire</span><span>上进行匹配时，如果与当前节点的关键字不能继续匹配的时候，就应该去当前节点的失败指针所指向的节点继续进行匹配。<br><span>&nbsp;&nbsp;&nbsp; 看下面这个例子：给定</span><span>5</span><span>个单词：</span><span>say&nbsp;she&nbsp;shr&nbsp;he&nbsp;her</span><span>，然后给定一个字符串</span><span>yasherhs</span><span>。</span><span>问一共有多少单词在这个字符串中出现过。我们先规定一下</span><span>AC</span><span>自动机所需要的一些数据结构，方便接下去的编程。<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;kind&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;node{&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">fail;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">失败指针</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">next[kind];&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Tire每个节点的个子节点（最多个字母）</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;count;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">是否为该单词的最后一个节点</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;node(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">构造函数初始化</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fail</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">NULL;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(next,NULL,</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(next));&nbsp;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">q[</span><span style="COLOR: #000000">500001</span><span style="COLOR: #000000">];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">队列，方便用于bfs构造失败指针</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;keyword[</span><span style="COLOR: #000000">51</span><span style="COLOR: #000000">];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">输入的单词</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;str[</span><span style="COLOR: #000000">1000001</span><span style="COLOR: #000000">];&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">模式串</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;head,tail;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">队列的头尾指针</span></div>
</span></span></span>
<p>&nbsp;</p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">有了这些数据结构之后，就可以开始编程了：<br>&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">首先，将这</span><span lang=EN-US><font face=Calibri>5</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">个单词构造成一棵</span><span lang=EN-US><font face=Calibri>Tire</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，如图</span><span lang=EN-US><font face=Calibri>-1</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">所示。<br>
<div align=center src_cetemp="/images/cppblog_com/mythit/ac1.jpg"><img height=394 alt="" src="http://www.cppblog.com/images/cppblog_com/mythit/ac1.jpg" width=611 border=0></div>
</span>
<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;insert(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">str,node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">root){&nbsp;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">root;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,index;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(str[i]){&nbsp;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">str[i]</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[index]</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL)&nbsp;p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[index]</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;node();&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[index];<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在单词的最后一个节点count+1，代表一个单词</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">}</span></div>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">在构造完这棵</span><span lang=EN-US><font face=Calibri>Tire</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">之后，接下去的工作就是构造下失败指针。构造失败指针的过程概括起来就一句话：设这个节点上的字母为</span><span lang=EN-US><font face=Calibri>C</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，沿着他父亲的失败指针走，直到走到一个节点，他的儿子中也有字母为</span><span lang=EN-US><font face=Calibri>C</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的节点。然后把当前节点的失败指针指向那个字母也为</span><span lang=EN-US><font face=Calibri>C</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的儿子。如果一直走到了</span><span lang=EN-US><font face=Calibri>root</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">都没找到，那就把失败指针指向</span><span lang=EN-US><font face=Calibri>root</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。具体操作起来只需要：<span style="COLOR: black">先把</span></span><span lang=EN-US style="COLOR: black"><font face=Calibri>root</font></span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">加入队列</span><span lang=EN-US style="COLOR: black"><font face=Calibri>(root</font></span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的失败指针指向自己或者</span><span lang=EN-US style="COLOR: black"><font face=Calibri>NULL)</font></span><span style="COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，这以后我们每处理一个点，就把它的所有儿子加入队列，队列为空。</span></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;build_ac_automation(node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">root){<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;root</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">NULL;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;q[head</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">root;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(head</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">tail){&nbsp;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">temp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">q[tail</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">];&nbsp;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">NULL;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">){&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i]</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">NULL){&nbsp;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(temp</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">root)&nbsp;temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i]</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">root;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">{&nbsp;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail;&nbsp;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">NULL){&nbsp;&nbsp;<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i]</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">NULL){&nbsp;<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i]</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i];&nbsp;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;&nbsp;<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&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;<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail;&nbsp;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL)&nbsp;temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i]</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">root;&nbsp;<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q[head</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[i];&nbsp;&nbsp;<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 从代码观察下构造失败指针的流程：<span>对照图</span><span>-2</span><span>来看，首先</span><span>root</span><span>的</span><span>fail</span><span>指针指向</span><span>NULL</span><span>，然后</span><span>root</span><span>入队，进入循环。第</span><span>1</span><span>次循环的时候，我们需要处理</span><span>2</span><span>个节点：</span><span>root-&gt;next[&#8216;h&#8217;-&#8216;a&#8217;](</span><span>节点</span><span>h) </span><span>和</span><span> root-&gt;next[&#8216;s&#8217;-&#8216;a&#8217;](</span><span>节点</span><span>s)</span><span>。把这</span><span>2</span><span>个节点的失败指针指向</span><span>root</span><span>，并且先后进入队列，失败指针的指向对应图</span><span>-2</span><span>中的</span><span>(1)</span><span>，</span><span>(2)</span><span>两条虚线；第</span><span>2</span><span>次进入循环后，从队列中先弹出</span><span>h</span><span>，接下来</span><span>p</span><span>指向</span><span>h</span><span>节点的</span><span>fail</span><span>指针指向的节点，也就是</span><span>root</span><span>；进入第</span><span>13</span><span>行的循环后，</span><span>p=p-&gt;fail</span><span>也就是</span><span>p=NULL</span><span>，这时退出循环，并把节点</span><span>e</span><span>的</span><span>fail</span><span>指针指向</span><span>root</span><span>，对应图</span><span>-2</span><span>中的</span><span>(3)</span><span>，然后节点</span><span>e</span><span>进入队列；第</span><span>3</span><span>次循环时，弹出的第一个节点</span><span>a</span><span>的操作与上一步操作的节点</span><span>e</span><span>相同，把</span><span>a</span><span>的</span><span>fail</span><span>指针指向</span><span>root</span><span>，对应图</span><span>-2</span><span>中的</span><span>(4)</span><span>，并入队；第</span><span>4</span><span>次进入循环时，弹出节点</span><span>h(</span><span>图中左边那个</span><span>)</span><span>，这时操作略有不同。在程序运行到</span><span>14</span><span>行时，由于</span><span>p-&gt;next[i]!=NULL(root</span><span>有</span><span>h</span><span>这个儿子节点，图中右边那个</span><span>)</span><span>，这样便把左边那个</span><span>h</span><span>节点的失败指针指向右边那个</span><span>root</span><span>的儿子节点</span><span>h</span><span>，对应图</span><span>-2</span><span>中的</span><span>(5)</span><span>，然后</span><span>h</span><span>入队。以此类推：在循环结束后，所有的失败指针就是图</span><span>-2</span><span>中的这种形式。<br>
<div align=center src_cetemp="/images/cppblog_com/mythit/ac2.JPG"><img height=394 alt="" src="http://www.cppblog.com/images/cppblog_com/mythit/ac2.JPG" width=611 border=0></div>
<br><font face=宋体>&nbsp;&nbsp;最后，我们便可以在AC自动机上查找模式串中出现过哪些单词了。匹配过程分两种情况：(1)当前字符匹配，表示从当前节点沿着树边有一条路径可以到达目标字符，此时只需沿该路径走向下一个节点继续匹配即可，目标字符串指针移向下个字符继续匹配；(2)当前字符不匹配，则去当前节点失败指针所指向的字符继续匹配，匹配过程随着指针指向root结束。重复这2个过程中的任意一个，直到模式串走到结尾为止。<br></font></span>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;query(node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">root){&nbsp;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,cnt</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,index,len</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">strlen(str);&nbsp;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">root;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(str[i]){&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">str[i]</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[index]</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;p</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">root)&nbsp;p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next[index];&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(p</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">NULL)</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">root:p;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">temp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p;&nbsp;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(temp</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">root&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">!=-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">){&nbsp;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count;&nbsp;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">=-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;&nbsp;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">temp</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">fail;&nbsp;<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;cnt;&nbsp;<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">}</span></div>
&nbsp;&nbsp;&nbsp; 对照图-2，看一下模式匹配这个详细的流程，其中模式串为yasherhs。对于i=0,1。Trie中没有对应的路径，故不做任何操作；i=2,3,4时，指针p走到左下节点e。因为节点e的count信息为1，所以cnt+1，并且讲节点e的count值设置为-1，表示改单词已经出现过了，防止重复计数，最后temp指向e节点的失败指针所指向的节点继续查找，以此类推，最后temp指向root，退出while循环，这个过程中count增加了2。表示找到了2个单词she和he。当i=5时，程序进入第5行，p指向其失败指针的节点，也就是右边那个e节点，随后在第6行指向r节点，r节点的count值为1，从而count+1，循环直到temp指向root为止。最后i=6,7时，找不到任何匹配，匹配过程结束。<br>
<img src ="http://www.cppblog.com/hello8706/aggbug/129020.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-10-08 10:52 <a href="http://www.cppblog.com/hello8706/archive/2010/10/08/129020.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>求无符号整数二进制数中1的个数</title><link>http://www.cppblog.com/hello8706/archive/2010/09/07/126097.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Tue, 07 Sep 2010 08:17:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/09/07/126097.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/126097.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/09/07/126097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/126097.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/126097.html</trackback:ping><description><![CDATA[今天公司和公司同事一起讨论五子棋的时候，他给我说了他的算法<br>这里五子棋的算法就不说啦<br>不过其实他的本质：<br>就是计算无符号整数中二进制中1的个数的思想<br>对此我也记录一下<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">//</span><span style="COLOR: #008000">获取正整数十进制的二进制数表示法</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;get2(unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n)<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{&nbsp;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nNum&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">保存最后的数（10进制数，2进制格式）</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;bDouble&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">是否是双数</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(n</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNum&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bDouble&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(;&nbsp;n&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;n&nbsp;</span><span style="COLOR: #000000">&gt;&gt;=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNum</span><span style="COLOR: #000000">*=</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNum</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">(&nbsp;n&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;);<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(bDouble)<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNum&nbsp;</span><span style="COLOR: #000000">-=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNum&nbsp;</span><span style="COLOR: #000000">/=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;nNum;&nbsp;<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">}&nbsp;<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;get2(</span><span style="COLOR: #000000">257</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;getchar();<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">}&nbsp;</span></div>
就是将十进制的数以二进制的格式保存（强调&#8220;格式&#8221;两个字！）<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">&nbsp;1&nbsp;//求正整数二进制中1的个数<br>&nbsp;<span style="COLOR: #000000">2&nbsp;int&nbsp;getoneNum(unsigned&nbsp;int&nbsp;n)</span><br>&nbsp;3&nbsp;{<br>&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;0;<br>&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(;&nbsp;n&nbsp;&gt;&nbsp;0;n&nbsp;&gt;&gt;=&nbsp;1)&nbsp;<br>&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i+=(&nbsp;n&nbsp;&amp;&nbsp;1&nbsp;);<br>&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;i;<br>10&nbsp;}<br>11&nbsp;//测试输出<br>12&nbsp;int&nbsp;main()<br>13&nbsp;{<br>14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;getoneNum(253);<br>15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getchar();<br>16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;&nbsp;<br>17&nbsp;}</div>
这样的时间复杂度是T(m)=m，取决于二进制数的位数m。如果要求在更短时间内求出，应该如何做呢？<br>其实大家都喜欢用的方法就是查表法，以空间换取时间。预先把结果存入表中（怎么存就自己写了呗~想一个一个算也是OK的，没有做不到，只有想不到），<br>然后直接通过下标就可以访问了。<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;tOne[</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;GetOneByArray(unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;n)<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="COLOR: #000000">-=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i;<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;n&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;n</span><span style="COLOR: #000000">&gt;&gt;=</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;tOne[n</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">255</span><span style="COLOR: #000000">];<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;i;<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;GetOneByArray(</span><span style="COLOR: #000000">255</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;getchar();<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">}</span></div>
这样的话，就可以直接读取1-256中1的个数了。在速度上达到的优化，通过tOne[x]就可以得到，连判断都可以不用，速度大大提升。<br>然后一个整型有4个字节，32位。1-256远远不够，难道要用1-2的32次方的表来保存？还是那句话，没有做不到，只有想不到。<br>OK，算一下如果要保存2的32次方个数的1的个数，那么这个数组的大小<br>至少2^32/(256/32)=512MB，哈哈，正是一般内存大小，搞定速度优化，应该还需要内存优化吧。空间换取时间也不能这么高的空间代价吧<br>于是需要再优化：存放1-256每个数中1的个数，然后分段查询。如上面把32位数分为4段，每段一个字节，所以有一个256大小供查询的表，比512M小太多了吧。<br>这样就能完成每个int数中二进制1的个数的查询了，站在巨人的肩上学习真好。<br><br>话说回来，我同事也用了这种有限的查表法来查询五子棋中某个下子点周围40个空格(当然，一般都小于40个）的状态变化，而状态就是一张表，其实也不多，数据量<br>比这个要大一些，不过写完的状态大概也只有几十K罢了，我还是喜欢先速度优化再内存优化的方式，因为这样可以让我最大限度的找到我个人认为比较综合有效的解决<br>方案。<br>
<img src ="http://www.cppblog.com/hello8706/aggbug/126097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-09-07 16:17 <a href="http://www.cppblog.com/hello8706/archive/2010/09/07/126097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>约瑟夫环的问题</title><link>http://www.cppblog.com/hello8706/archive/2010/03/16/109801.html</link><dc:creator>小火球</dc:creator><author>小火球</author><pubDate>Tue, 16 Mar 2010 01:56:00 GMT</pubDate><guid>http://www.cppblog.com/hello8706/archive/2010/03/16/109801.html</guid><wfw:comment>http://www.cppblog.com/hello8706/comments/109801.html</wfw:comment><comments>http://www.cppblog.com/hello8706/archive/2010/03/16/109801.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hello8706/comments/commentRss/109801.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hello8706/services/trackbacks/109801.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;1/**//*&nbsp;约瑟夫环问题(Josephus)&nbsp;&nbsp;2原题：&nbsp;&nbsp;3&nbsp;用户输入M,N值，从1至N开始顺序循环数数，每数到M输出该数值，直至全部输出。写出C程序。（约瑟夫环问题&nbsp;Josephus）&nbsp;&nbsp;4&nbsp;&nbsp;5提示：&nbsp;&nbsp;6&nbsp;&nbsp;&nb...&nbsp;&nbsp;<a href='http://www.cppblog.com/hello8706/archive/2010/03/16/109801.html'>阅读全文</a><img src ="http://www.cppblog.com/hello8706/aggbug/109801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hello8706/" target="_blank">小火球</a> 2010-03-16 09:56 <a href="http://www.cppblog.com/hello8706/archive/2010/03/16/109801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>