﻿<?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++博客-蓝莓日记Cass#-随笔分类-数据结构</title><link>http://www.cppblog.com/Cass/category/17852.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 14 Oct 2011 09:03:01 GMT</lastBuildDate><pubDate>Fri, 14 Oct 2011 09:03:01 GMT</pubDate><ttl>60</ttl><item><title>归并排序</title><link>http://www.cppblog.com/Cass/archive/2011/10/13/158249.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Thu, 13 Oct 2011 11:34:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/13/158249.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/158249.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/13/158249.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/158249.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/158249.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 归并排序（Merge sort）是建立在归并操作上的一种有效的排序算法，该算法是采用分治法。<br>　　申请空间，使其大小为两个已经排序序列之和，该空间用来存放合并后的序列 <br>　　设定两个指针，最初位置分别为两个已经排序序列的起始位置 <br>　　比较两个指针所指向的元素，选择相对小的元素放入到合并空间，并移动指针到下一位置 <br>　　重复步骤3直到某一指针达到序列尾 &nbsp;&nbsp;<a href='http://www.cppblog.com/Cass/archive/2011/10/13/158249.html'>阅读全文</a><img src ="http://www.cppblog.com/Cass/aggbug/158249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-13 19:34 <a href="http://www.cppblog.com/Cass/archive/2011/10/13/158249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>B-树及B＋树</title><link>http://www.cppblog.com/Cass/archive/2011/10/05/157576.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Wed, 05 Oct 2011 11:09:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/05/157576.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157576.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/05/157576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157576.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157576.html</trackback:ping><description><![CDATA[<p>1、B树的定义<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>B树是一种平衡的多分树（m叉树），通常我们说m阶的B树，它必须满足如下条件：<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>（1）每个结点至多有m个子结点；<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><wbr><wbr><wbr><wbr>（2）若根结点不是叶子结点，则至少有<span style="color: #ff0000">两棵子树；</span><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>（3）所有的叶结点在同一层；<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>（4）有k个子结点的非根结点恰好包含k-1个关键码。</p>
<p><span style="color: #0000ff"><font color="#000000">2、B-树数据结构</font><br />#define</span><span style="color: #000000"> M 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">B-树的阶，暂设为4</span><span style="color: #000000"><br /></span><span style="color: #0000ff">#define</span><span style="color: #000000"> false 0</span><span style="color: #000000"><br /></span><span style="color: #0000ff">#define</span><span style="color: #000000"> true 1</span><span style="color: #000000"><br /><br />typedef </span><span style="color: #0000ff">struct</span><span style="color: #000000"> BTNode<br />{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keynum;&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; </span><span style="color: #0000ff">struct</span><span style="color: #000000"> BTNode&nbsp;&nbsp;&nbsp; </span><span style="color: #000000">*</span><span style="color: #000000">parent;&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; </span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key[M</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">关键字向量，0号单元未用</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">struct</span><span style="color: #000000"> BTNode&nbsp;&nbsp;&nbsp; </span><span style="color: #000000">*</span><span style="color: #000000">son[M</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">子树指针向量<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">Record&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *recptr[M+1];&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">记录指针向量，0号单元未用(文件中使用)</span><span style="color: #008000"><br /></span><span style="color: #000000">}BTNode, </span><span style="color: #000000">*</span><span style="color: #000000">BTree;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">B-树节点和B-树的类型</span><span style="color: #008000"><br /></span><span style="color: #000000"><br />typedef </span><span style="color: #0000ff">struct</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp; BTNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #000000">*</span><span style="color: #000000">pt;&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; </span><span style="color: #0000ff">int</span><span style="color: #000000"> pos; </span><span style="color: #008000">//</span><span style="color: #008000">1...m,在节点中的关键字序号</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tag;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">1:查找成功，0:查找失败</span><span style="color: #008000"><br /></span><span style="color: #000000">}Result;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">B-树的查找结果类型<br /><br /></span><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"> init_BTree(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">root)<br />{<br />&nbsp;&nbsp;&nbsp; root</span><span style="color: #000000">=</span><span style="color: #000000">NULL;<br />}<br />
<p>2、B树的查找 <br />&nbsp;&nbsp;&nbsp;&nbsp;B树上的查找是一个顺指针查找结点和在结点内的关键码中查找交叉进行的过程。<span style="color: red">从根结点开始</span>，在结点包含的关键码中查找给定的关键码，找到则查找成功；否则确定给定关键码可能在的子树，重复上面的操作，直到查找成功或者指针为空为止。 <br />&nbsp;&nbsp;&nbsp;&nbsp;下图显示了在B树中查找关键码21的过程。 <br />
<div align="center"><img alt="" src="http://www.jpk.pku.edu.cn/pkujpk/course/sjjg/chapter10/03/images/01_01.gif" width="530" height="150" /><br /></div>
<p><br /></span><span style="color: #0000ff">int</span><span style="color: #000000"> search(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">p,</span><span style="color: #0000ff">int</span><span style="color: #000000"> key)<br />{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> j;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">for</span><span style="color: #000000">(j</span><span style="color: #000000">=</span><span style="color: #800080">1</span><span style="color: #000000">; j</span><span style="color: #000000">&lt;=</span><span style="color: #000000">p</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum; j</span><span style="color: #000000">++</span><span style="color: #000000">)<br />&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">key[j] </span><span style="color: #000000">&gt;</span><span style="color: #000000"> key)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">return</span><span style="color: #000000"> j</span><span style="color: #000000">-</span><span style="color: #800080">1</span><span style="color: #000000">;&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">}<br />Result searchBtree(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">root, </span><span style="color: #0000ff">int</span><span style="color: #000000"> key)<br />{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">在m阶B树t上查找关键码key，反回(pt,i,tag)。<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">若查找成功，则特征值tag=1，指针pt所指结点中第i个关键码等于key；<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">否则，特征值tag=0,等于key的关键码记录,应插入在指针pt所指结点中第i个和第i+1个关键码之间</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> found</span><span style="color: #000000">=</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> i;<br />&nbsp;&nbsp;&nbsp; BTree p</span><span style="color: #000000">=</span><span style="color: #000000">root,father</span><span style="color: #000000">=</span><span style="color: #000000">NULL;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">初始化，p指向待查节点，q指向p的双亲</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; Result&nbsp;&nbsp;&nbsp; result;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">SearchBTree函数返回值</span><span style="color: #008000"><br /></span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">while</span><span style="color: #000000">(p </span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000"> </span><span style="color: #000000">!</span><span style="color: #000000">found)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i</span><span style="color: #000000">=</span><span style="color: #000000">search(p,key);&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">p-&gt;node[i].key&#8804;K&lt;p-&gt;node[i+1].key</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(i</span><span style="color: #000000">&gt;</span><span style="color: #800080">0</span><span style="color: #000000"> </span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000"> p</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[i]</span><span style="color: #000000">==</span><span style="color: #000000">key)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; found</span><span style="color: #000000">=</span><span style="color: #0000ff">true</span><span style="color: #000000">;&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; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">else</span><span style="color: #000000"> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; father</span><span style="color: #000000">=</span><span style="color: #000000">p;<br />&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">son[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; result.pos</span><span style="color: #000000">=</span><span style="color: #000000">i</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">pos是插入的位置,记住加1</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(found)&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; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.pt</span><span style="color: #000000">=</span><span style="color: #000000">p;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.tag</span><span style="color: #000000">=</span><span style="color: #800080">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">查找不成功，返回key的插入位置i</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.pt</span><span style="color: #000000">=</span><span style="color: #000000">father;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.tag</span><span style="color: #000000">=</span><span style="color: #800080">0</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">return</span><span style="color: #000000"> result;<br />}</span><span style="color: #008000">//</span><span style="color: #008000">SearchBTree<br /></span>&nbsp;</p>
<p>3、B树的插入 <br />&nbsp;&nbsp;&nbsp;&nbsp;首先是在恰当的叶子结点中添加关键码，如果该结点中关键码不超过m-1个，则插入成功。否则要把这个结点分裂为两个。并把中间的一个关键码拿出来插到结点的父结点里去。父结点也可能是满的，就需要再分裂，再往上插。最坏的情况，这个过程可能一直传到根，如果需要分裂根，由于根是没有父结点的，这时就建立一个新的根结点。插入可能导致B树朝着根的方向生长。&nbsp;<br /><br />B-树的生成从空树开始，逐个插入关键字而得。关键字的个数必须至少为[m/2]-1，每次插入总在最底层某个终端结点添加一个关键字，如果该结点关键字个数小于m-1则直接插入，如果发现新插入关键字后，关键字总数超过m-1个则结点需要分裂，做法如下： 
<div class="spctrl"></div>
<p>　　(a)假设结点p中已经含有m-1个关键字，再插入一个关键字之后(插入总要保持关键字数组的大小有序，从小到大排好序)，可以将p分裂为p和p&#8217;，其中p含有的信息为[m/2]-1([m]表示大于m的最小整数)，p&#8217;含有的信息为m-[m/2] ([m]表示大于m的最小整数)。然后将关键字K[m/2]和指向p&#8217;的指针则一起插入到p的双亲结点中去。 
<div class="spctrl"></div>
<p>　　(b)检查双亲结点，如果双亲结点出现(a)的情况，则回到步骤a继续执行。直到插入满足条件为止，树的深度增加过程是随着插入而自下而上生长的过程。<br />&nbsp;&nbsp;&nbsp;&nbsp;下图显示了在B树中插入关键码33的过程。 <br />
<div align="center"><img alt="" src="http://www.jpk.pku.edu.cn/pkujpk/course/sjjg/chapter10/03/images/01_02.gif" width="530" height="130" /><br /></div>
<p><br /><span style="color: #0000ff">void</span><span style="color: #000000"> split(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">q, </span><span style="color: #0000ff">int</span><span style="color: #000000"> s, BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">ap)<br />{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000"> 将结点q分裂成两个结点，前一半保留，后一半移入新生结点ap</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> i;<br />&nbsp;&nbsp;&nbsp; cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800000">"</span><span style="color: #800000">分裂!</span><span style="color: #800000">"</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800000">"</span><span style="color: #800000">&nbsp; </span><span style="color: #800000">"</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[s]</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">endl;<br />&nbsp;&nbsp;&nbsp; ap</span><span style="color: #000000">=</span><span style="color: #000000">(BTree)malloc(</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(BTNode));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">生成新结点ap</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; ap</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[</span><span style="color: #800080">0</span><span style="color: #000000">] </span><span style="color: #000000">=</span><span style="color: #000000"> q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[s];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">原来结点中间位置关键字相应指针指向的子树放到新生成结点的0棵子树中去</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">for</span><span style="color: #000000">(i</span><span style="color: #000000">=</span><span style="color: #000000">s</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;=</span><span style="color: #000000">M;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">后一半移入ap</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ap</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[i</span><span style="color: #000000">-</span><span style="color: #000000">s]</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ap</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[i</span><span style="color: #000000">-</span><span style="color: #000000">s]</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[i];<br />&nbsp;&nbsp;&nbsp; }</span><span style="color: #008000">//</span><span style="color: #008000">for</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; ap</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum</span><span style="color: #000000">=</span><span style="color: #000000">M</span><span style="color: #000000">-</span><span style="color: #000000">s;<br />&nbsp;&nbsp;&nbsp; ap</span><span style="color: #000000">-&gt;</span><span style="color: #000000">parent</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">parent;<br />&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum</span><span style="color: #000000">=</span><span style="color: #000000">s</span><span style="color: #000000">-</span><span style="color: #800080">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">q的前一半保留，修改keynum</span><span style="color: #008000"><br /></span><span style="color: #000000">}</span><span style="color: #008000">//</span><span style="color: #008000">split</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> NewRoot(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">root, </span><span style="color: #0000ff">int</span><span style="color: #000000"> x, BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">ap)&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">{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">生成含信息(root,r,ap)的新的根结点*root，原root和ap为子树指针</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; BTree p;<br />&nbsp;&nbsp;&nbsp; p</span><span style="color: #000000">=</span><span style="color: #000000">(BTree)malloc(</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(BTNode));<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(root)&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; root</span><span style="color: #000000">-&gt;</span><span style="color: #000000">parent</span><span style="color: #000000">=</span><span style="color: #000000">p;&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; p</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[</span><span style="color: #800080">0</span><span style="color: #000000">]</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;&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; root</span><span style="color: #000000">=</span><span style="color: #000000">p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">root指向新根&nbsp;&nbsp;&nbsp; </span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; root</span><span style="color: #000000">-&gt;</span><span style="color: #000000">parent</span><span style="color: #000000">=</span><span style="color: #000000">NULL;&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; root</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum</span><span style="color: #000000">=</span><span style="color: #800080">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; root</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[</span><span style="color: #800080">1</span><span style="color: #000000">]</span><span style="color: #000000">=</span><span style="color: #000000">x;&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; root</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[</span><span style="color: #800080">1</span><span style="color: #000000">]</span><span style="color: #000000">=</span><span style="color: #000000">ap;&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; </span><span style="color: #0000ff">if</span><span style="color: #000000">(ap)&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; ap</span><span style="color: #000000">-&gt;</span><span style="color: #000000">parent</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; </span><span style="color: #008000">//</span><span style="color: #008000">原来的根中分裂出来的节点的双亲指针指向新根</span><span style="color: #008000"><br /></span><span style="color: #000000">}</span><span style="color: #008000">//</span><span style="color: #008000">NewRoot</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> insert(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">q, </span><span style="color: #0000ff">int</span><span style="color: #000000"> i, </span><span style="color: #0000ff">int</span><span style="color: #000000"> key, BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">ap)&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">插入</span><span style="color: #008000"><br /></span><span style="color: #000000">{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> j;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">for</span><span style="color: #000000">(j</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum; j</span><span style="color: #000000">&gt;=</span><span style="color: #000000">i; j</span><span style="color: #000000">--</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[j</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">]</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[j];<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[i]</span><span style="color: #000000">=</span><span style="color: #000000">key;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">for</span><span style="color: #000000">(j</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum; j</span><span style="color: #000000">&gt;=</span><span style="color: #000000">i; j</span><span style="color: #000000">--</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[j</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">]</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[j];<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">son[i]</span><span style="color: #000000">=</span><span style="color: #000000">ap;<br />&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum</span><span style="color: #000000">++</span><span style="color: #000000">;<br />}</span><span style="color: #008000">//</span><span style="color: #008000">insert</span><span style="color: #008000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> insertBtree(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">root, </span><span style="color: #0000ff">int</span><span style="color: #000000"> key, BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">q, </span><span style="color: #0000ff">int</span><span style="color: #000000"> i)<br />{<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">在B-树T上节点q的key[i]和key[i+1]之间插入关键字key<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">若引起节点过大，则沿双亲链进行必要的节点分裂整理，使T仍是M阶的B-树</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; BTree ap</span><span style="color: #000000">=</span><span style="color: #000000">NULL;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> x</span><span style="color: #000000">=</span><span style="color: #000000">key;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> finished </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">int</span><span style="color: #000000"> s;<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">while</span><span style="color: #000000">(q </span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000"> </span><span style="color: #000000">!</span><span style="color: #000000">finished)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert(q, i, x, ap);&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">将key和ap分别插入到q-&gt;key[i+1]和q-&gt;son[i+1]</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">keynum </span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp; M)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finished </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">true</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">插入完成</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">分裂结点*q</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s</span><span style="color: #000000">=</span><span style="color: #000000">ceil(M</span><span style="color: #000000">/</span><span style="color: #800080">2</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">key[s];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; split(q, s, ap);&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">将q-&gt;key[s+1...M],q-&gt;son[s...M]和q-&gt;recptr[s+1...M]移入到新节点*ap</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q</span><span style="color: #000000">=</span><span style="color: #000000">q</span><span style="color: #000000">-&gt;</span><span style="color: #000000">parent;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(q)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i</span><span style="color: #000000">=</span><span style="color: #000000">search(q,x)</span><span style="color: #000000">+</span><span style="color: #800080">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">在双亲结点*q中去查找x的插入位置,记住加1，因为search()返回的是插入位置的前一位</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">else</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; }</span><span style="color: #008000">//</span><span style="color: #008000">while</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">!</span><span style="color: #000000">finished)&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">root是空树(参数q初值为NULL)或者根节点已分裂为节点*q和*ap</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewRoot(root, x, ap);&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">生成含信息(root,x,ap)的新的根节点*root，原root和ap为子树指针</span><span style="color: #008000"><br /></span><span style="color: #000000">}</span><span style="color: #008000">//</span><span style="color: #008000">insertBtree</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000"> SearchInsertBTree(BTree </span><span style="color: #000000">&amp;</span><span style="color: #000000">root,</span><span style="color: #0000ff">int</span><span style="color: #000000"> key)</span><span style="color: #008000">//</span><span style="color: #008000">搜索插入</span><span style="color: #008000"><br /></span><span style="color: #000000">{ <br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">在m阶B树*t上结点*q的key[i],key[i+1]之间插入关键码key<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">若引起结点过大，则沿双亲链进行必要的结点分裂调整，使*t仍为m阶B树</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; Result&nbsp;&nbsp;&nbsp; rs;<br />&nbsp;&nbsp;&nbsp; rs </span><span style="color: #000000">=</span><span style="color: #000000"> searchBtree(root,key);<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">!</span><span style="color: #000000">rs.tag)&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">tag=0查找不成功，插入</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800000">"</span><span style="color: #800000">树中没有相同的节点，插入!</span><span style="color: #800000">"</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertBtree(root, key, rs.pt, rs.pos);&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">在B-树T上节点re.pt的key[i]和key[i+1]之间插入关键字key</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800000">"</span><span style="color: #800000">树中已有相同的节点!</span><span style="color: #800000">"</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">endl;<br />&nbsp;&nbsp;&nbsp; }<br />}</span><span style="color: #008000">//</span><span style="color: #008000">InserBTree</span></p>
<p>4、B树的删除 <br />&nbsp;&nbsp;&nbsp;&nbsp;B树中的删除操作与插入操作类似，但要稍微复杂些。如果删除的关键码不在叶结点层，则先把此关键码与它在B树里的后继对换位置，然后再删除该关键码。如果删除的关键码在叶结点层，则把它从它所在的结点里去掉，这可能导致此结点所包含的关键码的个数小于 -1。这种情况下，考察该结点的左或右兄弟，从兄弟结点移若干个关键码到该结点中来(这也涉及到它们的父结点中的一个关键码要做相应变化)，使两个结点所含关键码个数基本相同。只有在兄弟结点的关键码个数也很少，刚好等于 -1时，这个移动不能进行。这种情况下，要把将删除关键码的结点，它的兄弟结点及它们的父结点中的一个关键码合并为一个结点。 <br /><br /><span style="color: red"><strong>B+树</strong></span><br />　B+树是应文件系统所需而出的一种<a href="http://baike.baidu.com/view/2228473.htm" target="_blank"><font color="#136ec2">B-树</font></a>的变型树。一棵m阶的B+树和m阶的B-树的差异在于： </p>
<div class="spctrl"></div>
<p>　　1.有n棵子树的结点中含有n个关键字。 </p>
<div class="spctrl"></div>
<p>　　2.所有的叶子结点中包含了全部关键字的信息，及指向含这些关键字记录的指针，且叶子结点本身依关键字的大小自小而大顺序链接。 </p>
<div class="spctrl"></div>
<p>　　3.所有的非终端结点可以看成是索引部分，结点中仅含其子树（根结点）中的最大（或最小）关键字。 </p>
<div class="spctrl"></div>
<p>　　通常在B+树上有两个头指针，一个指向根结点，一个指向关键字最小的叶子结点。<br /></p>
<p>&nbsp;</p>
<h3 class="headline-2 bk-sidecatalog-title"><span class="headline-content">1、B+树的查找</span></h3>
<p>　　对B+树可以进行两种查找运算： </p>
<div class="spctrl"></div>
<p>　　1.从最小关键字起顺序查找； </p>
<div class="spctrl"></div>
<p>　　2.从根结点开始，进行随机查找。 </p>
<div class="spctrl"></div>
<p>　　在查找时，若非终端结点上的剧组机等于给定值，并不终止，而是继续向下直到叶子结点。因此，在B+树中，不管查找成功与否，每次查找都是走了一条从根到叶子结点的路径。其余同B-树的查找类似。 </p>
<h3 class="headline-2 bk-sidecatalog-title"><span class="headline-content">2、B+树的插入</span></h3>
<p>　　m阶B树的插入操作在叶子结点上进行，假设要插入关键值a，找到叶子结点后插入a，做如下算法判别： </p>
<div class="spctrl"></div>
<p>　　&#9312;如果当前结点是根结点并且插入后结点关键字数目小于等于m，则算法结束； </p>
<div class="spctrl"></div>
<p>　　&#9313;如果当前结点是非根结点并且插入后结点关键字数目小于等于m，则判断若a是新索引值时转步骤&#9315;后结束，若a不是新索引值则直接结束； </p>
<div class="spctrl"></div>
<p>　　&#9314;如果插入后关键字数目大于m(阶数)，则结点先分裂成两个结点X和Y，并且他们各自所含的关键字个数分别为：u=大于(m+1)/2的最小整数，v=小于(m+1)/2的最大整数； </p>
<div class="spctrl"></div>
<p>　　由于索引值位于结点的最左端或者最右端，不妨假设索引值位于结点最右端，有如下操作： </p>
<div class="spctrl"></div>
<p>　　如果当前分裂成的X和Y结点原来所属的结点是根结点，则从X和Y中取出索引的关键字，将这两个关键字组成新的根结点，并且这个根结点指向X和Y，算法结束； </p>
<div class="spctrl"></div>
<p>　　如果当前分裂成的X和Y结点原来所属的结点是非根结点，依据假设条件判断，如果a成为Y的新索引值，则转步骤&#9315;得到Y的双亲结点P，如果a不是Y结点的新索引值，则求出X和Y结点的双亲结点P；然后提取X结点中的新索引值a&#8217;，在P中插入关键字a&#8217;，从P开始，继续进行插入算法； </p>
<div class="spctrl"></div>
<p>　　&#9315;提取结点原来的索引值b，自顶向下，先判断根是否含有b，是则需要先将b替换为a，然后从根结点开始，记录结点地址P，判断P的孩子是否含有索引值b而不含有索引值a，是则先将孩子结点中的b替换为a，然后将P的孩子的地址赋值给P，继续搜索，直到发现P的孩子中已经含有a值时，停止搜索，返回地址P。 </p>
<h3 class="headline-2 bk-sidecatalog-title"><span class="headline-content">3、B+树的删除</span></h3>
<p>　　B+树的删除也仅在叶子结点进行，当叶子结点中的最大关键字被删除时，其在非终端结点中的值可以作为一个&#8220;分界关键字&#8221;存在。若因删除而使结点中关键字的个数少于m/2 （m/2结果取<a href="http://baike.baidu.com/view/45901.htm" target="_blank"><font color="#136ec2">上界</font></a>，如5/2结果为3）时，其和兄弟结点的合并过程亦和B-树类似。 </p>
<div class="spctrl"></div>
<p>　　另外的看法，当作补充和丰富吧。B树，B-树和B+树是三个不同的概念。<br />&nbsp;<br /><span style="color: red"><strong>B树</strong></span><br /></p>
<div class="bpctrl"></div>
<p>　　二叉排序树（Binary Sort Tree）又称二叉查找树，也叫B树。 </p>
<div class="spctrl"></div>
<p>　　它或者是一棵空树；或者是具有下列性质的二叉树： </p>
<div class="spctrl"></div>
<p>　　(1)若左子树不空，则左子树上所有结点的值均小于左子树所在树的根结点的值； </p>
<div class="spctrl"></div>
<p>　　(2)若右子树不空，则右子树上所有结点的值均大于右子树所在树的根结点的值； </p>
<div class="spctrl"></div>
<p>　　(3)左、右子树也分别为二叉排序树； <br /><br /><br /><br /></p>
<h3 class="headline-2 bk-sidecatalog-title"><span class="headline-content">1、二叉排序树（B树）的查找：</span></h3>
<p>　　时间复杂度与树的深度的有关。 </p>
<div class="spctrl"></div>
<p>　　步骤：若根结点的关键字值等于查找的关键字，成功。 </p>
<div class="spctrl"></div>
<p>　　否则：若小于根结点的关键字值，递归查左子树。 </p>
<div class="spctrl"></div>
<p>　　若大于根结点的关键字值，递归查右子树。 </p>
<div class="spctrl"></div>
<p>　　若子树为空，查找不成功。 </p>
<h3 class="headline-2 bk-sidecatalog-title"><span class="headline-content">2、二叉排序树（B树）的插入和删除：</span></h3>
<p>　　二叉排序树是一种动态树表。其特点是：树的结构通常不是一次生成的，而是在查找过程中，当树中不存在关键字等于给定值的节点时再进行插入。新插入的结点一定是一个新添加的叶子节点，并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。 </p>
<div class="spctrl"></div>
<p>　　插入算法： </p>
<div class="spctrl"></div>
<p>　　首先执行查找算法，找出被插结点的父亲结点。 </p>
<div class="spctrl"></div>
<p>　　判断被插结点是其父亲结点的左儿子还是右儿子。将被插结点作为叶子结点插入。 </p>
<div class="spctrl"></div>
<p>　　若二叉树为空。则首先单独生成根结点。 </p>
<div class="spctrl"></div>
<p>　　注意：新插入的结点总是叶子结点，所以算法复杂度是O(h)。 </p>
<div class="spctrl"></div>
<p>　　删除算法： </p>
<div class="spctrl"></div>
<p>　　如果删除的结点没有孩子，则删除后算法结束； </p>
<div class="spctrl"></div>
<p>　　如果删除的结点只有一个孩子，则删除后该孩子取代被删除结点的位置； </p>
<div class="spctrl"></div>
<p>　　如果删除的结点有两个孩子，则选择右孩子为根的树，它的左子树中，值最小的点作为新的根，同时在该最小值处开始，执行删除算法，如此继续到删除算法的前两种情况时，删除算法结束。 </p>
<div class="spctrl"></div>
<p>　　B树用途：查找信息快速，但是随着查找深度的增加，会影响查找的效率，所以，通常会使用平衡二叉树的平衡算法来进行动态平衡。</p> <img src ="http://www.cppblog.com/Cass/aggbug/157576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-05 19:09 <a href="http://www.cppblog.com/Cass/archive/2011/10/05/157576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>平衡二叉树 （AVL树）</title><link>http://www.cppblog.com/Cass/archive/2011/10/04/157454.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Mon, 03 Oct 2011 17:09:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/04/157454.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157454.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/04/157454.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157454.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157454.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1、平衡二叉树它是一棵空树或它的左右两个子树的高度差的绝对值不超过1，并且左右两个子树都是一棵平衡二叉树。　如图：2、动态平衡技术 动态平衡技术Adelson-Velskii 和 Landis 提出了一个动态地保持二叉排序树平衡的方法，其基本思想是：　　在构造二叉排序树的过程中，每当插入一个结点时，首先检查是否因插入而破坏了树的平衡性，如果是因插入结点而破坏了树的平衡性，则找出其中最小不平衡子树，...&nbsp;&nbsp;<a href='http://www.cppblog.com/Cass/archive/2011/10/04/157454.html'>阅读全文</a><img src ="http://www.cppblog.com/Cass/aggbug/157454.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-04 01:09 <a href="http://www.cppblog.com/Cass/archive/2011/10/04/157454.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各种查找算法的实现</title><link>http://www.cppblog.com/Cass/archive/2011/10/03/157399.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Mon, 03 Oct 2011 03:00:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/03/157399.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157399.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/03/157399.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157399.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157399.html</trackback:ping><description><![CDATA[1、顺序查找：（有两种方法）<br />在一个已知无(或有序）序队列中找出与给定关键字相同的数的具体位置。<br />&#9312;、让关键字与队列中的值从<span style="color: red">第一个开始</span>逐个比较，直到找出与给定关键字相同的值为止。 <br /><font face="宋体">&nbsp; int SeqSearch(Seqlist R，KeyType K)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在顺序表R[1..n]中顺序查找关键字为K的结点，<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //成功时返回找到的结点位置，失败时返回-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;R.len;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(R[i].key==K) return i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1；&nbsp;<br />&nbsp;&nbsp;&nbsp; } //SeqSearch</font><br /><br />&#9313;、从表中最后一个记录开始，逐个进行与关键字比较。直至第一个值，elem[0]=key，为设置&#8220;哨兵&#8221;。找不到返回0<br /><font face="宋体">&nbsp; int SeqSearch(Seqlist R，KeyType K)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在顺序表R[1..n]中顺序查找关键字为K的结点，<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //成功时返回找到的结点位置，失败时返回0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; R[0].key=K； //<span style="color: red">设置哨兵</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=R.len；R[i].key!=K;i--)； //从表后往前找<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i； //若i为0，表示查找失败，否则R[i]是要找的结点<br />&nbsp;&nbsp;&nbsp; } //SeqSearch</font><br />比较：<font face="宋体"><strong>成功时的顺序查找的平均查找长度：<br /></strong>&nbsp;&nbsp;&nbsp;&nbsp;</font><span style="font-family: 'Times New Roman'; font-size: 10.5pt" lang="EN-US"><span><font face="宋体"><img alt="" src="http://student.zjzk.cn/course_ware/data_structure/web/chazhao/chazha2.gif" width="369" height="49" v:shapes="_x0000_i1025" /></font></span>&nbsp;</span><br /><font face="宋体">&nbsp;&nbsp;&nbsp; 　在等概率情况下，p<sub>i</sub>=1/n(1&#8804;i&#8804;n)，故成功的平均查找长度为<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (n+&#8230;+2+1)/n=(n+1)/2<br />即查找成功时的平均比较次数约为表长的一半。<br />若K值不在表中，则须进行n+1次比较之后才能确定查找失败。<br /><br />2、折半查找：（二分法查找）(必须有序)<span style="font-family: 'Times New Roman','serif'; font-size: 9pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="font-size: 12pt; mso-tab-count: 2">&#9312;、假设数据是按升序排序的，对于给定值x，从序列的中间位置开始比较，如果当前位置值等于x，则查找成功；<br /></span><span style="font-size: 12pt; mso-tab-count: 2">&#9313;、若x小于当前位置值，则在数列的前半段中查找；若x大于当前位置值则在数列的后半段中继续查找，直到找到为止。</span><span style="font-size: 12pt; mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 10pt; mso-tab-count: 2">&nbsp;&nbsp;<br /></span><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="宋体">int search(int *a,int key,int low,int high)&nbsp;</font><br /></span></span>&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int mid;<br />　&nbsp;&nbsp;&nbsp;&nbsp;mid = (low + high)/2; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(low&lt;high)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(a[mid] == key) return mid;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (a[mid]&gt;key)&nbsp;&nbsp;&nbsp;high=mid;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp; &nbsp;low=mid;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mid = (low + high)/2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}//while<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;&nbsp;&nbsp;&nbsp; //没有找到<br />&nbsp;&nbsp;&nbsp;}//<font size="2">search</font><br /><span style="color: red">用递归思想：</span><br />　int search(int *a,int key,int low,int high) 
<div class="spctrl"></div>　　{ 
<div class="spctrl"></div>　&nbsp;&nbsp;&nbsp;　int mid; 
<div class="spctrl"></div>　　&nbsp;&nbsp;&nbsp;if(low &gt; high) 
<div class="spctrl"></div>　&nbsp;&nbsp;&nbsp;　return -1; 
<div class="spctrl"></div>　&nbsp;&nbsp;&nbsp;　mid = (low + high)/2; 
<div class="spctrl"></div>　&nbsp;&nbsp;&nbsp;　if(a[mid] == key) return mid; 
<div class="spctrl"></div>　&nbsp;&nbsp;&nbsp;　else if(a[mid] &gt; key)&nbsp;&nbsp;&nbsp;return search(a,key,low,mid -1); 
<div class="spctrl"></div>　&nbsp;&nbsp;&nbsp;　else return&nbsp;&nbsp;&nbsp;&nbsp;search(a,key,mid + 1,high); 
<div class="spctrl"></div>　　} <br /><br />3、<br /></font>/////////////////////待续...<br /><br /><img src ="http://www.cppblog.com/Cass/aggbug/157399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-03 11:00 <a href="http://www.cppblog.com/Cass/archive/2011/10/03/157399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二叉搜索树（二叉排序树）（二叉查找树）</title><link>http://www.cppblog.com/Cass/archive/2011/10/03/157397.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Mon, 03 Oct 2011 02:07:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/03/157397.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157397.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/03/157397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157397.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157397.html</trackback:ping><description><![CDATA[1、二叉搜索树是二叉树的一种，树的每个结点含有一个数据项，每个数据项有一个键值。结点的存储位置是由键值的大小决定的，所以二叉搜索树是关联式容器。<br />(1)、&nbsp;若它的左子树不空，则左子树上所有结点的键值均小于它的根结点的键值； <br />(2)、若它的右子树不空，则右子树上所有结点的键值均大于它的根结点的键值； <br />(3)、它的左、右子树也分别为二叉排序树。<br />注意：：：二叉排序树是一种<span style="color: red">动态树表</span>，树的结构通常不是一次生成的。而是在查找的过程中，当树中不存在关键字等于给定值的节点时再进行插入。新插入的结点一定是一个新添加的<font color="#136ec2">叶子结点</font>，并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。<br /><br />2、插入与查找算法：<br />查找：<br /><font size="2">（1）、若二叉排序树非空，将给定值与根节点的关键字值比较，若相等，则查找成功；<br />（2）、若不等，则当根节点的关键字值大于给定值时，到根的左子树中进行查找；<br />（3）、否则到根的右子树中进行查找。若找到，则查找过程是走了一条从树根到所找到节点的路径；<br />（4）、否则，查找过程终止于一棵空树。<br /><font size="2">//&#9312; 、普通查找，查找不成功返回NULL<br /></font><span style="color: red">递归思想：</span><br />&nbsp;BiTree SearchBST (BiTree *T，KeyType key)<br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp;//在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素<br />&nbsp;&nbsp;&nbsp;&nbsp;//若查找成功，则返回指向该数据元素结点的指针，否则返回空指针<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( (!T)||(key==T&#8212;&gt;data.key))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (T)； //查找结束,此时T为NULL，或者为该结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (key&lt; T&#8212;&gt;data.key)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(SearchBST(T&#8212;&gt;lchild，key))； //在左子树中继续查找<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(SearchBST(T &#8212;&gt;rchild，key))；// 在右子树中继续查找<br />&nbsp;&nbsp;&nbsp;&nbsp;}//SearchBST<br /><br /><span style="color: red">非递归思想：<br /><font size="2"><span style="color: #000000">BiTree SearchBST (BiTree *<font size="2">root</font>，KeyType key)</span></font><br /></span><span>{&nbsp;<br />&nbsp;&nbsp;&nbsp;<span style="color: #000000"><font size="2">BiTree </font></span>*p；<br /></span><span>&nbsp;&nbsp;&nbsp;if( root ＝＝ NULL)return NULL；<font size="2">//查找结束,此时根为NULL，</font><br /></span><span>&nbsp;&nbsp;&nbsp;p ＝ root；<br /></span><span>&nbsp;&nbsp;&nbsp;while(p!=NULL)<br /></span><span>&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="2">&nbsp;&nbsp;if(<font size="2">p －&gt;key==Key</font>)breat；</font><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( Key &lt; p -&gt;key) p ＝p －&gt;<font size="2">lchild</font>；<font size="2">//在左子树中继续查找</font><br /></span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else p ＝ p －&gt;<font size="2">rchild</font>；//<font size="2">在右子树中继续查找</font><br /></span><span>&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span>&nbsp;&nbsp;&nbsp;return p；<br /></span><span>}</span><br /><font size="2">//&#9313; 、查找不成功，返回插入位置<br /><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;//在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素，<br />&nbsp;&nbsp;&nbsp;&nbsp;//若查找成功，则指针p指向该数据元素结点，并返回TRUE，<br />&nbsp;&nbsp;&nbsp;&nbsp;//否则指针p指向查找路径上访问的最后一个结点并返回FALSE，<br />&nbsp;&nbsp;&nbsp;&nbsp;//指针f指向T的双亲，其初始调用值为NULL</font><br />&nbsp;BOOL SearchBST(BiTree *T，KeyType key，BiTree *f，BiTree &amp;p)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!T) {p=f；return FALSE；} //查找不成功<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (key==T&#8212;&gt;data.key)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{p=T；return TRUE；} //查找成功<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (key&lt;T&#8212;&gt;data.key) SearchBST(T&#8212;&gt;lchild，key，T，p)； //在左子树中继续查找<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;else SearchBST(T&#8212;&gt;rchild，key，T，p)；//在右子树中继续查找<br />&nbsp;&nbsp;&nbsp;&nbsp;}//SearchBST<br /><br /></font>插入：<br />（1）、首先执行查找算法，找出被插结点的父亲结点。没找到则新建子结点 
<div class="spctrl"></div>（2）、判断被插结点是其父亲结点的左、右儿子。将被插结点作为<a href="http://baike.baidu.com/view/2335663.htm" target="_blank">叶子结点</a>插入。 
<div class="spctrl"></div>（3）、若二叉树为空。则首先单独生成根结点<br /></font><br /><strong>基于<font size="2">BOOL SearchBST(BiTree *T，KeyType key，BiTree *f，BiTree &amp;p)</font>的插入算法<br /></strong>相当于新建子树。<br />&nbsp;//当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回TRUE，否则返回FALSE<br />Status Insert BST(BiTree &amp;T，ElemType e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!SearchBST(T，e.key，NULL，p)&nbsp;) //返回P为插入的结点点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>{</strong> //先查找，不成功新建结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s=(BiTree)malloc(sizeof(BiTNode))；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s-&gt;data=e； s-&gt;lchild= s-&gt;rchild=NULL； <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!p) T = s； //被插结点*s为新的根结点 ，原树为空<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (e.key&lt;p-&gt;data.key) p-&gt;lchild=s； //被插结点*s为左孩子<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else p&#8212;&gt;rchild=s //被插结点*s为右孩子<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return TRUE；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>&nbsp;&nbsp;&nbsp;}<br /></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return FALSE; //树中已有关键字相同的结点，不再插入<br />&nbsp;&nbsp;&nbsp;&nbsp;}// Insert BST<br /><br /><font size="2">&nbsp; void InsertBST(BSTree *Tptr，KeyType key)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br />//若二叉排序树 *Tptr中没有关键字为key，则插入，否则直接返回<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BSTNode *f，*p=*TPtr； //p的初值指向根结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(p){ //查找插入位置<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p-&gt;key==key) return；//树中已有key，无须插入<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f=p； //<span style="color: #ff0000">f保存当前查找的结点</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p=(key&lt;p-&gt;key)?p-&gt;lchild：p-&gt;rchild；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //若key&lt;p-&gt;key，则在左子树中查找，否则在右子树中查找<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } //endwhile<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff0000">//f为插入的结点</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p=(BSTNode *)malloc(sizeof(BSTNode))；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p-&gt;key=key； p-&gt;lchild=p-&gt;rchild=NULL； //生成新结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(*TPtr==NULL) //<span style="color: #ff0000">原树</span>为空<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *Tptr=p； //新插入的结点为新的根<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else //原树非空时将新结点关p作为关f的左孩子或右孩子插入<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(key&lt;f-&gt;key)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f-&gt;lchild=p；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else f-&gt;rchild=p；<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } //InsertBST</font><br /><br />4、删除算法<br /><strong>&#9312;删除操作的一般步骤<br /></strong>(1) 进行查找<br />&nbsp;&nbsp;&nbsp; 　查找时，令p指向当前访问到的结点，parent指向其双亲(其初值为NULL)。若树中找不到被删结点则返回，否则被删结点是*p。<br />(2) 删去*p。<br />&nbsp;&nbsp;&nbsp; 　删*p时，应将*p的子树(若有)仍连接在树上且保持BST性质不变。按*p的孩子数目分三种情况进行处理。<br /><br /><strong>&#9313;删除*p结点的三种情况</strong><br />(1)*p是叶子(即它的孩子数为0)<br />&nbsp;&nbsp;&nbsp; 　无须连接*p的子树，只需将*p的双亲*parent中指向*p的指针域置空即可。<br /><br />(2)*p只有一个孩子*child<br />&nbsp;&nbsp;&nbsp; 　只需将*child和*p的双亲直接连接后，即可删去*p。<br />&nbsp; <font color="#ff0000">注意：</font><br />&nbsp;&nbsp;&nbsp; 　*p既可能是*parent的左孩子也可能是其右孩子，而*child可能是*p的左孩子或右孩子，故共有4种状态。<br />(3)*p有两个孩子<br />&nbsp;&nbsp;&nbsp; 　先令q=p，将被删结点的地址保存在q中；然后找*q的中序后继*p，并在查找过程中仍用parent记住*p的双亲位置。*q的中序后继*p一定是*q的右子树中最左下的结点，它无左子树。因此，可以将删去*q的操作转换为删去的*p的操作，即在释放结点*p之前将其数据复制到*q中，就相当于删去了*q。<br /><strong>&#9314;二叉排序树删除算法</strong> <font color="#ff00ff"><br /></font>分析：<br />&nbsp;&nbsp;&nbsp; 　上述三种情况都能统一到情况(2)，算法中只需针对情况(2)处理即可。<br />&nbsp;&nbsp;&nbsp; 　注意边界条件：若parent为空，被删结点*p是根，故删去*p后，应将child置为根。<br /><br /><br />算法：删除关键字为key的结点 <br />void DelBSTNode(BSTree *Tptr，KeyType key)<br />&nbsp;{<br />//在二叉排序树*Tptr中删去关键字为key的结点<br />&nbsp; BSTNode *parent=NUll，*p=*Tptr，*q，*child；<br />&nbsp; while(p)<br /><strong>{&nbsp;<br /></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//从根开始查找关键字为key的待删结点<br />&nbsp;&nbsp;&nbsp; if(p-&gt;key==key) break；//已找到，跳出查找循环<br />&nbsp;&nbsp;&nbsp; parent=p； //parent指向*p的双亲<br />&nbsp;&nbsp;&nbsp; p=(key&lt;p-&gt;key)?p-&gt;lchild：p-&gt;rchild； //在关p的左或右子树中继续找<br /><strong>&nbsp;}&nbsp; <br />//注意：也可以使用<strong>基于<font size="2">BOOL SearchBST(BiTree *T，KeyType key，BiTree *f，BiTree &amp;p)</font>的查找算法</strong><br />//结果是&nbsp; parent 记录了要删除结点的父结点，p指向要删除的结点<br /><br /></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!p) return； //找不到被删结点则返回<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q=p； //q记住被删结点*p<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(q-&gt;lchild &amp;&amp; q-&gt;rchild) //*q的两个孩子均非空，故找*q的中序后继*p<br />&nbsp;&nbsp;&nbsp; for(parent=q，p=q-&gt;rchild； p-&gt;lchild； parent=p，p=p=-&gt;lchild)；<br />&nbsp; //现在情况(3)已被转换为情况(2)，而情况(1)相当于是情况(2)中child=NULL的状况<br />&nbsp;&nbsp;&nbsp; child=(p-&gt;lchild)?p-&gt;lchild：p-&gt;rchild；//若是情况(2)，则child非空；否则child为空<br />&nbsp;&nbsp;&nbsp; if(!parent) //*p的双亲为空，说明*p为根，删*p后应修改根指针<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *Tptr=child； //若是情况(1)，则删去*p后，树为空；否则child变为根<br />&nbsp;&nbsp;&nbsp; else{ //*p不是根，将*p的孩子和*p的双亲进行连接，*p从树上被摘下<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p==parent-&gt;lchild) //*p是双亲的左孩子<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent-&gt;lchild=child； //*child作为*parent的左孩子<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else parent-&gt;rchild=child； //*child作为 parent的右孩子<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p!=q) //是情况(3)，需将*p的数据复制到*q<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q-&gt;key=p-&gt;key； //若还有其它数据域亦需复制<br />&nbsp;&nbsp;&nbsp;&nbsp; } //endif<br />&nbsp;&nbsp;&nbsp; free(p)； /释放*p占用的空间<br />&nbsp; } //DelBSTNode<br /><strong>给出三种情况的不同算法<br /><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><strong>第一种：</strong></span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><br /></span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">btree&nbsp;*&nbsp;DelNode(btree&nbsp;*p)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(p-&gt;lchild)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btree&nbsp;*r&nbsp;=&nbsp;p-&gt;lchild;&nbsp;&nbsp;&nbsp;//r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">指向其左子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(r-&gt;rchild&nbsp;!=&nbsp;NULL)//</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">搜索左子树的最右边的叶子结点</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;=&nbsp;r-&gt;rchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r-&gt;rchild&nbsp;=&nbsp;p-&gt;rchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btree&nbsp;*q&nbsp;=&nbsp;p-&gt;lchild;&nbsp;&nbsp;&nbsp;//q</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">指向其左子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;q;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btree&nbsp;*q&nbsp;=&nbsp;p-&gt;rchild;&nbsp;&nbsp;&nbsp;//q</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">指向其右子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;q;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><strong>第二种：</strong></span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><br /></span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">btree&nbsp;*&nbsp;DelNode(btree&nbsp;*p)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(p-&gt;lchild)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btree&nbsp;*r&nbsp;=&nbsp;p-&gt;lchild;&nbsp;&nbsp;&nbsp;//r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">指向其左子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btree&nbsp;*prer&nbsp;=&nbsp;p-&gt;lchild;&nbsp;&nbsp;&nbsp;//prer</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">指向其左子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(r-&gt;rchild&nbsp;!=&nbsp;NULL)//</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">搜索左子树的最右边的叶子结点</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prer&nbsp;=&nbsp;r;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;=&nbsp;r-&gt;rchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(prer&nbsp;!=&nbsp;r)//</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">若</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">不是</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">p</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的左孩子，把</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的左孩子作为</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的父亲的右孩子</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prer-&gt;rchild&nbsp;=&nbsp;r-&gt;lchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r-&gt;lchild&nbsp;=&nbsp;p-&gt;lchild;&nbsp;//</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">被删结点</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">p</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的左子树作为</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的左子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r-&gt;rchild&nbsp;=&nbsp;p-&gt;rchild;&nbsp;//</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">被删结点</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">p</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的右子树作为</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">r</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的右子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US"><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;r;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btree&nbsp;*q&nbsp;=&nbsp;p-&gt;rchild;&nbsp;&nbsp;&nbsp;//q</span><span style="font-family: 宋体; color: #222222; font-size: 10.5pt; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">指向其右子树</span><span style="font-family: 'Verdana','sans-serif'; color: #222222; font-size: 10.5pt; mso-bidi-font-family: 宋体; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang="EN-US">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;q;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br style="mso-special-character: line-break" /><br style="mso-special-character: line-break" /></span><br /><br /></span></strong><img src ="http://www.cppblog.com/Cass/aggbug/157397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-03 10:07 <a href="http://www.cppblog.com/Cass/archive/2011/10/03/157397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>哈夫曼树</title><link>http://www.cppblog.com/Cass/archive/2011/10/02/157353.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Sun, 02 Oct 2011 09:04:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/02/157353.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157353.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/02/157353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157353.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157353.html</trackback:ping><description><![CDATA[<p>哈夫曼树定义为：给定n个权值作为n个叶子结点，构造一棵二叉树，若带权路径长度达到最小，称这样的二叉树为最优二叉树，也称为哈夫曼树(Huffman tree)。<br />1、那么什么是<span style="color: red">权值</span>？什么是<span style="color: red">路径长度</span>？什么是带<span style="color: red">权路径长度</span>呢？<br /><span style="color: red">权值</span>：哈夫曼树的权值是自己定义的，他的物理意义表示数据出现的次数、频率。可以用树的每个结点数据域data存放一个特定的数表示它的值。<span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="line-height: 24px; font-family: arial, 宋体, sans-serif; font-size: 14px" class="Apple-style-span"></p>
<p><span style="color: red">路径长度</span>：在一棵树中，从一个结点往下可以达到的孩子或子孙结点之间的通路，称为路径。<span style="color: red">通路中分支的数目</span></span></span>称为路径长度。若规定根结点的层数为1，则从根结点到第L层结点的路径长度为L-1。<br /><br /><span style="color: red">结点的带权路径长度</span>为：从根结点到该结点之间的路径长度与该结点的权的乘积。&nbsp; 树中所有叶子节点的带权路径长度之和，<span style="color: red">WPL=sigma(w*l)</span><br /><br />2、哈夫曼树的构造过程。（结合图例）<br />假设有n个权值，则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、&#8230;、wn，则哈夫曼树的构造规则为： </p>
<div class="spctrl"></div>
<p>　　(1) 将w1、w2、&#8230;，wn看成是有n 棵树的森林(每棵树仅有一个结点)； </p>
<div class="spctrl"></div>
<p>　　(2) 在森林中选出两个根结点的权值最小的树合并，作为一棵新树的左、右子树，且新树的根结点权值为其左、右子树根结点权值之和； </p>
<div class="spctrl"></div>
<p>　　(3)从森林中删除选取的两棵树，并将新树加入森林； </p>
<div class="spctrl"></div>
<p>　　(4)重复(2)、(3)步，直到森林中只剩一棵树为止，该树即为所求得的哈夫曼树<br /><br />3、哈夫曼树的应用：哈夫曼编码（前缀编码）<br /><strong>哈夫曼编码</strong> </p>
<p>在数据通信中，通常需要把要传送的文字转换为由二进制字符0和1组成的二进制串，这个过程被称之为编码(Encoding)。例如，假设要传送的电文为DCBBADD，电文中只有A、B、C、D四种字符，若这四个字符采用表(a)所示的编码方案，则电文的代码为11100101001111，代码总长度为14。若采用表(b) 所示的编码方案，则电文的代码为0110101011100，代码总长度为13。</p>
<p align="center"><span><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/cass/编码1.jpg" /><br /></span><br />字符集的不同编码方案</p>
<p>哈夫曼树可用于构造总长度最短的编码方案。具体构造方法如下：<br />设需要编码的字符集为{d1,d2,&#8230;,dn}，各个字符在电文中出现的次数或频率集合为{w1,w2,&#8230;,wn}。以d1,d2,&#8230;,dn作为叶子结点，以w1,w2,&#8230;,wn作为相应叶子结点的权值来构造一棵哈夫曼树。规定哈夫曼树中的左分支代表0，右分支代表1，则从根结点到叶子结点所经过的路径分支组成的0和1的序列便为该结点对应字符的编码就是哈夫曼编码(Huffman Encoding)。</p>
<p>在建立不等长编码中，必须使任何一个字符的编码都不是另一个编码的前缀，这样才能保证译码的唯一性。例如，若字符A的编码是00，字符B的编码是001，那么字符A的编码就成了字符B的编码的后缀。这样，对于代码串001001，在译码时就无法判定是将前两位码00译成字符A还是将前三位码001译成B。这样的编码被称之为具有二义性的编码，二义性编码是不唯一的。而在哈夫曼树中，每个字符结点都是叶子结点，它们不可能在根结点到其它字符结点的路径上，所以一个字符的哈夫曼编码不可能是另一个字符的哈夫曼编码的前缀，从而保证了译码的非二义性。</p>
<p>下图就是电文DCBBADD的哈夫曼树：</p>
<p align="center"><span><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/cass/编码2.jpg" width="403" height="299" /><br /></span></p>
<p><br /><strong>4、哈夫曼树的实现</strong> </p>
<p>由哈夫曼树的构造算法可知，用一个数组存放原来的n个叶子结点和构造过程中临时生成的结点，数组的大小为2n-1。所以，哈夫曼树类HuffmanTree中有两个成员字段：data数组用于存放结点，leafNum表示哈夫曼树叶子结点的数目。结点有四个域，一个域weight，用于存放该结点的权值；一个域lChild，用于存放该结点的左孩子结点在数组中的序号；一个域rChild，用于存放该结点的右孩子结点在数组中的序号；一个域parent，用于判定该结点是否已加入哈夫曼树中。</p>
<p>哈夫曼树结点的结构为：| 数据 | weight | lChild | rChild | parent |</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; public class Node<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char c; //存储的数据，为一个字符<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private double weight; //结点权值<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int lChild; //左孩子结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int rChild; //右孩子结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int parent; //父结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //结点权值属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public double Weight<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weight = value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //左孩子结点属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int LChild<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return lChild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lChild = value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //右孩子结点属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int RChild<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rChild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rChild = value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //父结点属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int Parent<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return parent;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent = value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //构造器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Node()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weight = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lChild = -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rChild = -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent = -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //构造器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Node(double weitht)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.weight = weitht;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lChild = -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rChild = -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent = -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //构造器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Node(int w, int lc, int rc, int p)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weight = w;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lChild = lc;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rChild = rc;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent = p;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; public class HuffmanTree<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Node[] data; //结点数组<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int leafNum; //叶子结点数目<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //索引器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Node this[int index]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return data[index];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[index] = value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //叶子结点数目属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int LeafNum<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return leafNum;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leafNum = value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //构造器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public HuffmanTree(int n)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new Node[2 * n - 1];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leafNum = n;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建哈夫曼树<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void Create(Node[] datain)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double minL, minR;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minL = minR = double.MaxValue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int lchild, rchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lchild = rchild = -1;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int length = data.Length;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //初始化哈夫曼树<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; length; i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i] = new Node();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; datain.Length; i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i] = datain[i];</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //处理n个叶子结点，建立哈夫曼树<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = leafNum; i &lt; length; i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //在全部结点中找权值最小的两个结点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; i; j++)<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (data[j].Parent == -1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (data[j].Weight &lt; minL)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minR = minL;<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; minL = data[j].Weight;<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; rchild = lchild;<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; lchild = j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (data[j].Weight &lt; minR)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minR = data[j].Weight;<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; rchild = j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[lchild].Parent = data[rchild].Parent = i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i].Weight = minL + minR;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i].LChild = lchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i].RChild = rchild;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; class Program<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HuffmanTree tree = new HuffmanTree(5);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node[] nodes = new Node[] { new Node(1), new Node(2), new Node(2.5d), new Node(3), new Node(2.6d) };<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tree.Create(nodes);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p>/////////////////////////////节选自网络上的资料、</p><img src ="http://www.cppblog.com/Cass/aggbug/157353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-02 17:04 <a href="http://www.cppblog.com/Cass/archive/2011/10/02/157353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优先队列</title><link>http://www.cppblog.com/Cass/archive/2011/10/02/157339.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Sun, 02 Oct 2011 03:22:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/02/157339.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157339.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/02/157339.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157339.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157339.html</trackback:ping><description><![CDATA[优先队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有<span style="color: red">最高优先权</span>的元素。每个元素都有一个优先权或值<br />/////用堆实现优先队列<br />1、把优先队列中的元素按优先级大小组织成堆，堆顶元素具有最大优先级。<br />2、优先队列的插入与删除可以用堆的插入与删除实现。<br />3、优先队列在定义为priority_queue ，在STL中#include&lt;queue&gt;&nbsp;中实现、<br />&nbsp;<span style="color: #000000">priority_queue</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">,&nbsp;vector</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">,&nbsp;greater</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">qi2;</span> 
<p>其中<br />第二个参数为容器类型。<br />第三个参数为比较函数。<br /><br /></p><br /><img src ="http://www.cppblog.com/Cass/aggbug/157339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-02 11:22 <a href="http://www.cppblog.com/Cass/archive/2011/10/02/157339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>堆排序</title><link>http://www.cppblog.com/Cass/archive/2011/10/01/157298.html</link><dc:creator>Yu_</dc:creator><author>Yu_</author><pubDate>Sat, 01 Oct 2011 08:55:00 GMT</pubDate><guid>http://www.cppblog.com/Cass/archive/2011/10/01/157298.html</guid><wfw:comment>http://www.cppblog.com/Cass/comments/157298.html</wfw:comment><comments>http://www.cppblog.com/Cass/archive/2011/10/01/157298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Cass/comments/commentRss/157298.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Cass/services/trackbacks/157298.html</trackback:ping><description><![CDATA[估计还要问问：什么是堆，什么是堆排序？堆与计算机分配内存的堆相同吗？<br />很多资料给出：堆的定义是<br />（1）、n个关键字序列（Kl，K2，&#8230;，Kn）称为(Heap)，当且仅当该序列满足如下性质(简称为堆性质)：<br />ki&#8804;K2i且ki&#8804;K2i+1 或&nbsp; Ki&#8805;K2i且ki&#8805;K2i+1 (1&#8804;i&#8804; n)&nbsp;//ki相当于二叉树的非叶结点，K2i则是左孩子，k2i+1是右孩子&nbsp;<br /><br />
<div class="spctrl"></div>（2）若将此序列所存储的向量R[1..n]看做是一棵<strong>完全二叉树</strong>的存储结构，则堆实质上是满足如下性质的完全二叉树： 
<div class="spctrl"></div>　　<strong>树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。<br /><br /></strong>（3）、根结点(亦称为堆顶)的关键字是堆里所有结点关键字中<span style="color: red">最小者</span>的堆称为<span style="color: red">小根堆</span>，又称最小堆。根结点(亦称为堆顶)的关键字是堆里所有结点关键字中<span style="color: red">最大者</span>，称为大根堆，又称<span style="color: red">最大堆。<br /><br /></span><span>（4）、堆中任一子树亦是堆。<br />（5）、堆可以视为一棵完全的二叉树，完全二叉树的一个&#8220;优秀&#8221;的性质是，除了最底层之外，每一层都是满的，这使得堆可以利用</span><span style="color: #ff6600">数组</span><span>来表示（普通的一般的二叉树通常用链表作为基本容器表示），每一个结点对应数组中的一个元素。</span><br /><br />那么堆排序呢？<br />堆排序其实就是将一组无序的序列变成堆的过程、下面我们一起看看堆排序的算法。<br />2、堆排序<br />以最大堆为例，步骤为：<br />　　&#9312; 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区 
<div class="spctrl"></div>　　&#9313; 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换，由此得到新的无序区R[1..n-1]和有序区R[n]，且满足R[1..n-1].keys&#8804;R[n].key 
<div class="spctrl"></div>　　&#9314;由于交换后新的根R[1]可能违反堆性质，故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换，由此得到新的无序区R[1..n-2]和有序区R[n-1..n]，且仍满足关系R[1..n-2].keys&#8804;R[n-1..n].keys，同样要将R[1..n-2]调整为堆。 
<div class="spctrl"></div>　　&#8230;&#8230; 
<div class="spctrl"></div>　　直到无序区只有一个元素为止。&nbsp;<span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="text-align: left; line-height: 23px; font-family: simsun; font-size: 14px" class="Apple-style-span"><span class="Apple-converted-space">&nbsp;</span><br />将一个无序的序列建成堆的过程实际上是一个反复筛选的过程。若将此序列看作是一棵完全二叉树，则最后一个非终端结点是[n/2](不大于n/2的整数），因此筛选过程只需从[n/2]开始。要建成一个大顶堆，即先选择一个值最大的元素并与序列中的最后一个元素交换，然后对序列前n-1元素进行筛选，从新调整为一个大顶堆，直到结束。<span class="Apple-converted-space">&nbsp;</span><br />算法描述如下：<span class="Apple-converted-space">&nbsp;</span><br />&nbsp;<span class="Apple-converted-space">&nbsp;</span><br />typedef &nbsp; int[] &nbsp; Elem;//采用顺序存储表示完全二叉树<span class="Apple-converted-space">&nbsp;</span><br /><br />void &nbsp; HeapAdjust(Elem &nbsp; &amp;e,int &nbsp; s,int &nbsp; m)<span class="Apple-converted-space">&nbsp;</span><br />{//e中s...m的元素除e[s]之外已经满足堆的定义（e[i] &lt;=e[2*i]&amp;&amp;e[i] &lt;=e[2*i+1]<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; //或e[i]&gt; =e[2*i]&amp;&amp;e[i]&gt; =e[2*i+1]),调整e[s]使的e[s...m]成为一个大顶堆。<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; selem=e[s];<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; for(i=2*s;i &lt;=m;i*=2)//沿着值较大的元素（结点）向下筛选<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; {<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(i &lt;m &nbsp; &amp;&amp; &nbsp; e[i] &lt;e[i+1])++i;//i为值较大的元素下标<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(selem&gt; =e[i])break;<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e[s]=e[i];<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s=i;<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; }<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; e[s]=selem;<span class="Apple-converted-space">&nbsp;</span><br />}<span class="Apple-converted-space">&nbsp;</span><br /><br />void &nbsp; HeapSort(Elem &nbsp; &amp;e)<span class="Apple-converted-space">&nbsp;</span><br />{//对顺序表排序<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; for(i=e.length/2;i&gt; 0;--i)<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HeapAdjust(e,i,e.length);<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; for(i=e.length;i&gt; 1;--i)<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; {<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; temp=e[1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //将堆中的最后一个元素与第一个元素交换<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e[1]=e[i];<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e[i]=temp;<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HeapAdjust(H,1,i-1);//调整1..i-1的元素成为大顶堆<span class="Apple-converted-space">&nbsp;</span><br />&nbsp; &nbsp; &nbsp; } &nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span><br />}<br /><br /><br />/////////////////////////////////////////////////////////////<br />使用堆排序注意的问题：：：<br /></span></span>1、序列是从1开始的。，注意定义，R[1..n]，故要空出R[0]。<br />2、堆排序算法分为两部分：建立大顶堆和排序。<br />3、排序的最坏时间复杂度为<strong>O(nlogn)</strong>。堆序的平均性能较接近于最坏性能。<br />4、由于建初始堆所需的比较次数较多，所以堆排序不适宜于记录数较少的文件。 
<div class="spctrl"></div>5、　堆排序是就地排序，辅助空间为O(1)， 它是<strong>不稳定</strong>的排序方法。<br /><br />问题：当序列空间为R[0,1....n]；时，该怎么去使用堆排序呢？元素后移一位，这明显不是一个好方法。<img src ="http://www.cppblog.com/Cass/aggbug/157298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Cass/" target="_blank">Yu_</a> 2011-10-01 16:55 <a href="http://www.cppblog.com/Cass/archive/2011/10/01/157298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>