??xml version="1.0" encoding="utf-8" standalone="yes"?>精品久久8x国产免费观看,久久精品人人做人人爽电影蜜月,久久久一本精品99久久精品88http://www.shnenglu.com/Cass/category/17852.htmlzh-cnFri, 14 Oct 2011 09:03:01 GMTFri, 14 Oct 2011 09:03:01 GMT60归ƈ排序http://www.shnenglu.com/Cass/archive/2011/10/13/158249.htmlYu_Yu_Thu, 13 Oct 2011 11:34:00 GMThttp://www.shnenglu.com/Cass/archive/2011/10/13/158249.htmlhttp://www.shnenglu.com/Cass/comments/158249.htmlhttp://www.shnenglu.com/Cass/archive/2011/10/13/158249.html#Feedback0http://www.shnenglu.com/Cass/comments/commentRss/158249.htmlhttp://www.shnenglu.com/Cass/services/trackbacks/158249.html  甌I间Q其大ؓ两个已经排序序列之和Q该I间用来存放合ƈ后的序列
  讑֮两个指针Q最初位|分别ؓ两个已经排序序列的v始位|?
  比较两个指针所指向的元素,选择相对的元素攑օ到合q空_q移动指针到下一位置
  重复步骤3直到某一指针辑ֈ序列?  阅读全文

Yu_ 2011-10-13 19:34 发表评论
]]>
B-树及BQ树http://www.shnenglu.com/Cass/archive/2011/10/05/157576.htmlYu_Yu_Wed, 05 Oct 2011 11:09:00 GMThttp://www.shnenglu.com/Cass/archive/2011/10/05/157576.htmlhttp://www.shnenglu.com/Cass/comments/157576.htmlhttp://www.shnenglu.com/Cass/archive/2011/10/05/157576.html#Feedback0http://www.shnenglu.com/Cass/comments/commentRss/157576.htmlhttp://www.shnenglu.com/Cass/services/trackbacks/157576.html1、B树的定义
    B树是一U^衡的多分树(m叉树Q,通常我们说m阶的B树,它必L_下条Ӟ
    Q?Q每个结点至多有m个子l点Q?br />    Q?Q若根结点不是叶子结点,则至有两棵子树Q?/span>
    Q?Q所有的叶结点在同一层;
    Q?Q有k个子l点的非根结Ҏ好包含k-1个关键码?/p>

2、B-树数据结?/font>
#define
M 4        //B-树的Ӟ暂设?
#define false 0
#define true 1

typedef
struct BTNode
{
   
int                keynum;            //节点中关键字个数Q即节点的大?/span>
    struct BTNode    *parent;        //指向双亲l点
    int                key[M+1];        //关键字向量,0号单元未?/span>
    struct BTNode    *son[M+1];        //子树指针向量
   
//Record        *recptr[M+1];    //记录指针向量Q?号单元未?文g中?
}BTNode, *BTree;        //B-树节点和B-树的cd

typedef
struct
{
    BTNode           
*pt;            //指向扑ֈ的节?/span>
    int pos; //1...m,在节点中的关键字序号
    int                tag;            //1:查找成功Q?:查找p|
}Result;        //B-树的查找l果cd

//初始?/span>
void init_BTree(BTree &root)
{
    root
=NULL;
}

2、B树的查找
    B树上的查找是一个顺指针查找l点和在l点内的关键码中查找交叉q行的过E?span style="color: red">从根l点开?/span>Q在l点包含的关键码中查扄定的关键码,扑ֈ则查找成功;否则定l定关键码可能在的子树,重复上面的操作,直到查找成功或者指针ؓIZؓ止?
    下图昄了在B树中查找关键?1的过E?



int search(BTree &p,int key)
{
   
int j;
   
for(j=1; j<=p->keynum; j++)
       
if(p->key[j] > key)
        {
           
break;
        }
   
return j-1;        //应该插入的位|的前一?/span>
}
Result searchBtree(BTree
&root, int key)
{
   
//在m阶B树t上查扑օ键码keyQ反?pt,i,tag)?br />    //若查找成功,则特征值tag=1Q指针pt所指结点中Wi个关键码{于keyQ?br />    //否则Q特征值tag=0,{于key的关键码记录,应插入在指针pt所指结点中Wi个和Wi+1个关键码之间
    int found=false;
   
int i;
    BTree p
=root,father=NULL;    //初始化,p指向待查节点Qq指向p的双?/span>
    Result    result;        //SearchBTree函数q回?/span>

   
while(p && !found)
    {
        i
=search(p,key);    //p->node[i].key≤K<p->node[i+1].key
        if(i>0 && p->key[i]==key)
        {
            found
=true;        //扑ֈ待查关键?/span>
        }
       
else
        {
            father
=p;
            p
=p->son[i];
        }
    }
    result.pos
=i+1;        //pos是插入的位置,C?
    if(found)    //查找成功
    {
        result.pt
=p;
        result.tag
=1;   
    }
   
else    //查找不成功,q回key的插入位|i
    {
        result.pt
=father;
        result.tag
=0;   
    }
   
return result;
}
//SearchBTree
 

3、B树的插入
    首先是在恰当的叶子结点中d关键码,如果该结点中关键码不过m-1个,则插入成功。否则要把这个结点分裂ؓ两个。ƈ把中间的一个关键码拿出来插到结点的父结炚w厅R父l点也可能是满的Q就需要再分裂Q再往上插。最坏的情况Q这个过E可能一直传到根Q如果需要分裂根Q由于根是没有父l点的,q时徏立一个新的根l点。插入可能导致B树朝着根的方向生长?nbsp;

B-树的生成从空树开始,逐个插入关键字而得。关键字的个数必至ؓ[m/2]-1Q每ơ插入d最底层某个l端l点d一个关键字Q如果该l点关键字个数小于m-1则直接插入,如果发现新插入关键字后,关键字L过m-1个则l点需要分裂,做法如下Q?

  (a)假设l点p中已l含有m-1个关键字Q再插入一个关键字之后(插入总要保持关键字数l的大小有序Q从到大排好序)Q可以将p分裂为p和p’Q其中p含有的信息ؓ[m/2]-1([m]表示大于m的最整?Qp’含有的信息ؓm-[m/2] ([m]表示大于m的最整?。然后将关键字K[m/2]和指向p’的指针则一h入到p的双亲结点中厅R?

  (b)查双亲结点,如果双亲l点出现(a)的情况,则回到步骤al箋执行。直到插入满x件ؓ止,树的深度增加q程是随着插入而自下而上生长的过E?br />    下图昄了在B树中插入关键?3的过E?



void split(BTree &q, int s, BTree &ap)
{
   
// 结点q分裂成两个结点,前一半保留,后一半移入新生结点ap
    int i;
    cout
<<"分裂!"<<"  "<<q->key[s]<<endl;
    ap
=(BTree)malloc(sizeof(BTNode));        //生成新结点ap
    ap->son[0] = q->son[s];            //原来l点中间位置关键字相应指针指向的子树攑ֈ新生成结点的0子树中?/span>
    for(i=s+1;i<=M;i++)        //后一半移入ap
    {
        ap
->key[i-s]=q->key[i];
        ap
->son[i-s]=q->son[i];
    }
//for
    ap->keynum=M-s;
    ap
->parent=q->parent;
    q
->keynum=s-1;        //q的前一半保留,修改keynum
}//split

void NewRoot(BTree &root, int x, BTree &ap)        //生成新的根节?/span>
{
   
//生成含信?root,r,ap)的新的根l点*rootQ原root和ap为子树指?/span>
    BTree p;
    p
=(BTree)malloc(sizeof(BTNode));
   
if(root)    //如果原来的树不是I树
        root->parent=p;                    //q来的根的双亲指针指向新?/span>
    p->son[0]=root;                        //新根的第一个孩子节Ҏ原来的根节点
    root=p;        //root指向新根   
    root->parent=NULL;                    //新根的双亲是I指?/span>
    root->keynum=1;           
    root
->key[1]=x;                        //新根的第一个关键字是前面分裂出来的关键字
    root->son[1]=ap;                    //新根的第二个孩子节点是原来的根中分裂出来的节?/span>
    if(ap)        //如果原来的树不是I树
        ap->parent=root;                //原来的根中分裂出来的节点的双亲指针指向新?/span>
}//NewRoot

void insert(BTree &q, int i, int key, BTree &ap)    //插入
{
   
int j;
   
for(j=q->keynum; j>=i; j--)
    {
        q
->key[j+1]=q->key[j];
    }
    q
->key[i]=key;
   
for(j=q->keynum; j>=i; j--)
    {
        q
->son[j+1]=q->son[j];
    }
    q
->son[i]=ap;
    q
->keynum++;
}
//insert
void insertBtree(BTree &root, int key, BTree &q, int i)
{
   
//在B-树T上节点q的key[i]和key[i+1]之间插入关键字key
   
//若引赯点过大,则沿双亲链进行必要的节点分裂整理QT仍是M阶的B-?/span>
    BTree ap=NULL;
   
int x=key;
   
int finished = false;
   
int s;
   
while(q && !finished)
    {
        insert(q, i, x, ap);   
//key和ap分别插入到q->key[i+1]和q->son[i+1]
        if(q->keynum <    M)
            finished
= true;    //插入完成
        else
        {   
//分裂l点*q
            s=ceil(M/2);
            x
=q->key[s];
            split(q, s, ap);   
//q->key[s+1...M],q->son[s...M]和q->recptr[s+1...M]Ud到新节点*ap
            q=q->parent;
           
if(q)
                i
=search(q,x)+1;        //在双亲结?q中去查找x的插入位|?C?Q因为search()q回的是插入位置的前一?/span>
        }//else
    }//while
    if(!finished)                //root是空?参数q初gؓNULL)或者根节点已分裂ؓ节点*q?ap
        NewRoot(root, x, ap);    //生成含信?root,x,ap)的新的根节点*rootQ原root和ap为子树指?/span>
}//insertBtree

void SearchInsertBTree(BTree &root,int key)//搜烦插入
{
   
//在m阶B?t上结?q的key[i],key[i+1]之间插入关键码key
   
//若引L点过大,则沿双亲链进行必要的l点分裂调整Q*t仍ؓm阶B?/span>
    Result    rs;
    rs
= searchBtree(root,key);
   
if(!rs.tag)    //tag=0查找不成功,插入
    {
        cout
<<"树中没有相同的节点,插入!"<<endl;
        insertBtree(root, key, rs.pt, rs.pos);   
//在B-树T上节点re.pt的key[i]和key[i+1]之间插入关键字key
    }
   
else
    {
        cout
<<"树中已有相同的节?"<<endl;
    }
}
//InserBTree

4、B树的删除
    B树中的删除操作与插入操作cMQ但要稍微复杂些。如果删除的关键码不在叶l点层,则先把此关键码与它在B树里的后l对换位|,然后再删除该关键码。如果删除的关键码在叶结点层Q则把它从它所在的l点里去掉,q可能导致此l点所包含的关键码的个数小?-1。这U情况下Q考察该结点的左或叛_弟,从兄弟结点移若干个关键码到该l点中来(q也涉及到它们的父结点中的一个关键码要做相应变化)Q两个l点所含关键码个数基本相同。只有在兄弟l点的关键码个数也很,刚好{于 -1Ӟq个Ud不能q行。这U情况下Q要把将删除关键码的l点Q它的兄弟结点及它们的父l点中的一个关键码合ƈZ个结炏V?

B+?/strong>
 B+树是应文件系l所需而出的一U?a target="_blank">B-?/font>的变型树。一m阶的B+树和m阶的B-树的差异在于Q?

  1.有n子树的l点中含有n个关键字?

  2.所有的叶子l点中包含了全部关键字的信息Q及指向含这些关键字记录的指针,且叶子结Ҏw依关键字的大小自小而大序链接?

  3.所有的非终端结点可以看成是索引部分Q结点中仅含其子树(根结点)中的最大(或最)关键字?

  通常在B+树上有两个头指针Q一个指向根l点Q一个指向关键字最的叶子l点?br />

 

1、B+树的查找

  对B+树可以进行两U查找运:

  1.从最关键字起顺序查找;

  2.从根l点开始,q行随机查找?

  在查找时Q若非终端结点上的剧l机{于l定|q不l止Q而是l箋向下直到叶子l点。因此,在B+树中Q不查找成功与否,每次查找都是C一条从根到叶子l点的\径。其余同B-树的查找cM?

2、B+树的插入

  m阶B树的插入操作在叶子结点上q行Q假设要插入关键值aQ找到叶子结点后插入aQ做如下法判别Q?

  ①如果当前l点是根l点q且插入后结点关键字数目于{于mQ则法l束Q?

  ②如果当前l点是非根结点ƈ且插入后l点关键字数目小于等于mQ则判断若a是新索引值时转步?#9315;后结束,若a不是新烦引值则直接l束Q?

  ③如果插入后关键字数目大于m(阶数)Q则l点先分裂成两个l点X和YQƈ且他们各自所含的关键字个数分别ؓQu=大于(m+1)/2的最整敎ͼv=于(m+1)/2的最大整敎ͼ

  ׃索引g于结点的最左端或者最右端Q不妨假讄引g于结Ҏ右端Q有如下操作Q?

  如果当前分裂成的X和Yl点原来所属的l点是根l点Q则从X和Y中取出烦引的关键字,这两个关键字组成新的根l点Qƈ且这个根l点指向X和YQ算法结束;

  如果当前分裂成的X和Yl点原来所属的l点是非根结点,依据假设条g判断Q如果a成ؓY的新索引|则{步骤④得到Y的双亲结点PQ如果a不是Yl点的新索引|则求出X和Yl点的双亲结点PQ然后提取Xl点中的新烦引值a’Q在P中插入关键字a’Q从P开始,l箋q行插入法Q?

  ④提取l点原来的烦引值bQ自向下,先判断根是否含有bQ是则需要先b替换为aQ然后从根结点开始,记录l点地址PQ判断P的孩子是否含有烦引值b而不含有索引值aQ是则先孩子结点中的b替换为aQ然后将P的孩子的地址赋值给PQl搜索,直到发现P的孩子中已经含有a值时Q停止搜索,q回地址P?

3、B+树的删除

  B+树的删除也仅在叶子结点进行,当叶子结点中的最大关键字被删除时Q其在非l端l点中的值可以作Z?#8220;分界关键?#8221;存在。若因删除而ɾl点中关键字的个数少于m/2 Qm/2l果?a target="_blank">上界Q如5/2l果?Q时Q其和兄弟结点的合ƈq程亦和B-树类伹{?

  另外的看法,当作补充和丰富吧。B树,B-树和B+树是三个不同的概c?br /> 
B?/strong>

  二叉排序树(Binary Sort TreeQ又UC叉查找树Q也叫B树?

  它或者是一늩树;或者是h下列性质的二叉树Q?

  (1)若左子树不空Q则左子树上所有结点的值均于左子树所在树的根l点的|

  (2)若右子树不空Q则叛_树上所有结点的值均大于叛_树所在树的根l点的|

  (3)左、右子树也分别ؓ二叉排序树;



1、二叉排序树QB树)的查找:

  旉复杂度与树的深度的有兟?

  步骤Q若根结点的关键字值等于查扄关键字,成功?

  否则Q若于根结点的关键字|递归查左子树?

  若大于根l点的关键字|递归查右子树?

  若子树ؓI,查找不成功?

2、二叉排序树QB树)的插入和删除Q?/span>

  二叉排序树是一U动态树表。其特点是:树的l构通常不是一ơ生成的Q而是在查找过E中Q当树中不存在关键字{于l定值的节点时再q行插入。新插入的结点一定是一个新d的叶子节点,q且是查找不成功时查找\径上讉K的最后一个结点的左孩子或叛_子结炏V?

  插入法Q?

  首先执行查找法Q找插结点的父亲l点?

  判断被插l点是其父亲l点的左儿子q是叛_子。将被插l点作ؓ叶子l点插入?

  若二叉树为空。则首先单独生成根结炏V?

  注意Q新插入的结ҎL叶子l点Q所以算法复杂度是O(h)?

  删除法Q?

  如果删除的结Ҏ有孩子,则删除后法l束Q?

  如果删除的结点只有一个孩子,则删除后该孩子取代被删除l点的位|;

  如果删除的结Ҏ两个孩子Q则选择叛_子ؓ根的树,它的左子树中Q值最的点作为新的根Q同时在该最值处开始,执行删除法Q如此l到删除法的前两种情况Ӟ删除法l束?

  B树用途:查找信息快速,但是随着查找深度的增加,会媄响查扄效率Q所以,通常会用^衡二叉树的^衡算法来q行动态^衡?/p>

Yu_ 2011-10-05 19:09 发表评论
]]>
q二叉?QAVL树)http://www.shnenglu.com/Cass/archive/2011/10/04/157454.htmlYu_Yu_Mon, 03 Oct 2011 17:09:00 GMThttp://www.shnenglu.com/Cass/archive/2011/10/04/157454.htmlhttp://www.shnenglu.com/Cass/comments/157454.htmlhttp://www.shnenglu.com/Cass/archive/2011/10/04/157454.html#Feedback0http://www.shnenglu.com/Cass/comments/commentRss/157454.htmlhttp://www.shnenglu.com/Cass/services/trackbacks/157454.html阅读全文

Yu_ 2011-10-04 01:09 发表评论
]]>
各种查找法的实?/title><link>http://www.shnenglu.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.shnenglu.com/Cass/archive/2011/10/03/157399.html</guid><wfw:comment>http://www.shnenglu.com/Cass/comments/157399.html</wfw:comment><comments>http://www.shnenglu.com/Cass/archive/2011/10/03/157399.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Cass/comments/commentRss/157399.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Cass/services/trackbacks/157399.html</trackback:ping><description><![CDATA[1、顺序查找:Q有两种ҎQ?br />在一个已知无(或有序)序队列中扑և与给定关键字相同的数的具体位|?br />①、让关键字与队列中的g<span style="color: red">W一个开?/span>逐个比较Q直到找Zl定关键字相同的gؓ止?<br /><font face="宋体">  int SeqSearch(Seqlist RQKeyType K)<br />    {<br />      //在顺序表R[1..n]中顺序查扑օ键字为K的结点,<br />      //成功时返回找到的l点位置Q失败时q回-1      <br />      int iQ?br />      for(i=0;i<R.len;i++)<br />      {<br />           if(R[i].key==K) return i;<br />       }<br />      return -1Q?nbsp;<br />    } //SeqSearch</font><br /><br />②、从表中最后一个记录开始,逐个q行与关键字比较。直至第一个|elem[0]=keyQؓ讄“哨兵”。找不到q回0<br /><font face="宋体">  int SeqSearch(Seqlist RQKeyType K)<br />    {<br />      //在顺序表R[1..n]中顺序查扑օ键字为K的结点,<br />      //成功时返回找到的l点位置Q失败时q回0<br />      int iQ?br />      R[0].key=KQ?//<span style="color: red">讄哨兵</span><br />      for(i=R.lenQR[i].key!=K;i--)Q?//从表后往前找<br />      return iQ?//若i?Q表C查扑֤败,否则R[i]是要扄l点<br />    } //SeqSearch</font><br />比较Q?font face="宋体"><strong>成功时的序查找的^均查N度:<br /></strong>    </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> </span><br /><font face="宋体">     在等概率情况下,p<sub>i</sub>=1/n(1≤i≤n)Q故成功的^均查N度ؓ<br />        (n+…+2+1)/n=(n+1)/2<br />x找成功时的^均比较次数约长的一半?br />若Kg在表中,则须q行n+1ơ比较之后才能确定查扑֤败?br /><br />2、折半查找:Q二分法查找Q?必须有序)<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">          <br /></span><span style="font-size: 12pt; mso-tab-count: 2">①、假设数据是按升序排序的Q对于给定值xQ从序列的中间位|开始比较,如果当前位置值等于xQ则查找成功Q?br /></span><span style="font-size: 12pt; mso-tab-count: 2">②、若x于当前位置|则在数列的前半段中查找;若x大于当前位置值则在数列的后半D中l箋查找Q直到找Cؓ止?/span><span style="font-size: 12pt; mso-tab-count: 2">      </span><span style="font-size: 10pt; mso-tab-count: 2">  <br /></span><span style="mso-tab-count: 2">      <font face="宋体">int search(int *a,int key,int low,int high) </font><br /></span></span>   {<br />      int mid;<br />     mid = (low + high)/2; <br />      while(low<high)<br />      {<br />         if(a[mid] == key) return mid; <br />         else <br />         if (a[mid]>key)   high=mid;<br />               else   low=mid;<br /><br />           mid = (low + high)/2;           <br />       }//while<br />      return -1;    //没有扑ֈ<br />   }//<font size="2">search</font><br /><span style="color: red">用递归思想Q?/span><br /> int search(int *a,int key,int low,int high) <div id="oymwaiy" class="spctrl"></div>  { <div id="eeqamca" class="spctrl"></div>     int mid; <div id="wqsoqgw" class="spctrl"></div>     if(low > high) <div id="akmqksi" class="spctrl"></div>     return -1; <div id="ucoauky" class="spctrl"></div>     mid = (low + high)/2; <div id="moikmwk" class="spctrl"></div>     if(a[mid] == key) return mid; <div id="qaeoaqo" class="spctrl"></div>     else if(a[mid] > key)   return search(a,key,low,mid -1); <div id="emyawkc" class="spctrl"></div>     else return    search(a,key,mid + 1,high); <div id="kcwqssa" class="spctrl"></div>  } <br /><br />3?br /></font>/////////////////////待箋...<br /><br /><img src ="http://www.shnenglu.com/Cass/aggbug/157399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Cass/" target="_blank">Yu_</a> 2011-10-03 11:00 <a href="http://www.shnenglu.com/Cass/archive/2011/10/03/157399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二叉搜烦树(二叉排序树)Q二叉查找树Q?/title><link>http://www.shnenglu.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.shnenglu.com/Cass/archive/2011/10/03/157397.html</guid><wfw:comment>http://www.shnenglu.com/Cass/comments/157397.html</wfw:comment><comments>http://www.shnenglu.com/Cass/archive/2011/10/03/157397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Cass/comments/commentRss/157397.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Cass/services/trackbacks/157397.html</trackback:ping><description><![CDATA[1、二叉搜索树是二叉树的一U,树的每个l点含有一个数据项Q每个数据项有一个键倹{结点的存储位置是由键值的大小军_的,所以二叉搜索树是关联式容器?br />(1)?nbsp;若它的左子树不空Q则左子树上所有结点的键值均于它的根结点的键| <br />(2)、若它的叛_树不I,则右子树上所有结点的键值均大于它的根结点的键| <br />(3)、它的左、右子树也分别ؓ二叉排序树?br />注意Q:Q二叉排序树是一U?span style="color: red">动态树?/span>Q树的结构通常不是一ơ生成的。而是在查扄q程中,当树中不存在关键字等于给定值的节点时再q行插入。新插入的结点一定是一个新d?font color="#136ec2">叶子l点</font>Qƈ且是查找不成功时查找路径上访问的最后一个结点的左孩子或叛_子结炏V?br /><br />2、插入与查找法Q?br />查找Q?br /><font size="2">Q?Q、若二叉排序树非I,给定g根节点的关键字值比较,若相{,则查找成功;<br />Q?Q、若不等Q则当根节点的关键字值大于给定值时Q到根的左子树中q行查找Q?br />Q?Q、否则到根的叛_树中q行查找。若扑ֈQ则查找q程是走了一条从树根到所扑ֈ节点的\径;<br />Q?Q、否则,查找q程l止于一늩树?br /><font size="2">//① 、普通查找,查找不成功返回NULL<br /></font><span style="color: red">递归思想Q?/span><br /> BiTree SearchBST (BiTree *TQKeyType key)<br />{ <br />    //在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元?br />    //若查找成功,则返回指向该数据元素l点的指针,否则q回I指?br />        if( (!T)||(key==T—>data.key))<br />            return (T)Q?//查找l束,此时T为NULLQ或者ؓ该结?br />        else if (key< T—>data.key)<br />                return(SearchBST(T—>lchildQkey))Q?//在左子树中l查?br />                else <br />                return(SearchBST(T —>rchildQkey))Q?/ 在右子树中l查?br />    }//SearchBST<br /><br /><span style="color: red">非递归思想Q?br /><font size="2"><span style="color: #000000">BiTree SearchBST (BiTree *<font size="2">root</font>QKeyType key)</span></font><br /></span><span>{ <br />   <span style="color: #000000"><font size="2">BiTree </font></span>*pQ?br /></span><span>   if( root Q= NULL)return NULLQ?font size="2">//查找l束,此时根ؓNULLQ?/font><br /></span><span>   p Q?rootQ?br /></span><span>   while(p!=NULL)<br /></span><span>   { <br />      <font size="2">  if(<font size="2">p Q?gt;key==Key</font>)breatQ?/font><br />       if( Key < p ->key) p Qp Q?gt;<font size="2">lchild</font>Q?font size="2">//在左子树中l查?/font><br /></span><span>         else p Q?p Q?gt;<font size="2">rchild</font>Q?/<font size="2">在右子树中l查?/font><br /></span><span>    }<br /></span><span>   return pQ?br /></span><span>}</span><br /><font size="2">//② 、查找不成功Q返回插入位|?br /><font size="2">    //在根指针T所指二叉排序树中递归地查扑օ关键字等于key的数据元素,<br />    //若查找成功,则指针p指向该数据元素结点,q返回TRUEQ?br />    //否则指针p指向查找路径上访问的最后一个结点ƈq回FALSEQ?br />    //指针f指向T的双Ԍ其初始调用gؓNULL</font><br /> BOOL SearchBST(BiTree *TQKeyType keyQBiTree *fQBiTree &p)<br />{<br />        if(!T) {p=fQreturn FALSEQ} //查找不成?br />        else if (key==T—>data.key) <br />            {p=TQreturn TRUEQ} //查找成功<br />           else if (key<T—>data.key) SearchBST(T—>lchildQkeyQTQp)Q?//在左子树中l查?br />                        else SearchBST(T—>rchildQkeyQTQp)Q?/在右子树中l查?br />    }//SearchBST<br /><br /></font>插入Q?br />Q?Q、首先执行查扄法,扑և被插l点的父亲结炏V没扑ֈ则新建子l点 <div id="ugawiaq" class="spctrl"></div>Q?Q、判断被插结Ҏ其父亲结点的左、右儿子。将被插l点作ؓ<a target="_blank">叶子l点</a>插入? <div id="eoscoom" class="spctrl"></div>Q?Q、若二叉树ؓI。则首先单独生成根结?br /></font><br /><strong>Z<font size="2">BOOL SearchBST(BiTree *TQKeyType keyQBiTree *fQBiTree &p)</font>的插入算?br /></strong>相当于新建子树?br /> //当二叉排序树T中不存在关键字等于e.key的数据元素时,插入eq返回TRUEQ否则返回FALSE<br />Status Insert BST(BiTree &TQElemType e)<br />{<br />            if(!SearchBST(TQe.keyQNULLQp) ) //q回P为插入的l点?br />        <strong>{</strong> //先查找,不成功新建结?br />            s=(BiTree)malloc(sizeof(BiTNode))Q?br />            s->data=eQ?s->lchild= s->rchild=NULLQ?<br />            if (!p) T = sQ?//被插l点*s为新的根l点 Q原树ؓI?br />            else if (e.key<p->data.key) p->lchild=sQ?//被插l点*s为左孩子<br />                    else p—>rchild=s //被插l点*s为右孩子<br />            return TRUEQ?br />       <strong>   }<br /></strong>        else <br />      return FALSE; //树中已有关键字相同的l点Q不再插?br />    }// Insert BST<br /><br /><font size="2">  void InsertBST(BSTree *TptrQKeyType key)<br />      { <br />//若二叉排序树 *Tptr中没有关键字为keyQ则插入Q否则直接返?br />        BSTNode *fQ?p=*TPtrQ?//p的初值指向根l点<br />        while(p){ //查找插入位置<br />          if(p->key==key) returnQ?/树中已有keyQ无L?br />          f=pQ?//<span style="color: #ff0000">f保存当前查找的结?/span><br />          p=(key<p->key)?p->lchildQp->rchildQ?br />            //若key<p->keyQ则在左子树中查找,否则在右子树中查?br />         } //endwhile<br />         <span style="color: #ff0000">//f为插入的l点</span><br />        p=(BSTNode *)malloc(sizeof(BSTNode))Q?br />        p->key=keyQ?p->lchild=p->rchild=NULLQ?//生成新结?br />        if(*TPtr==NULL) //<span style="color: #ff0000">原树</span>为空<br />           *Tptr=pQ?//新插入的l点为新的根<br />        else //原树非空时将新结点关p作ؓ关f的左孩子或右孩子插入<br />          if(key<f->key)<br />            f->lchild=pQ?br />          else f->rchild=pQ?br />       } //InsertBST</font><br /><br />4、删除算?br /><strong>①删除操作的一般步?br /></strong>(1) q行查找<br />     查找Ӟ令p指向当前讉K到的l点Qparent指向其双?其初gؓNULL)。若树中找不到被删结点则q回Q否则被删结Ҏ*p?br />(2) 删去*p?br />     ?pӞ应将*p的子?若有)仍连接在树上且保持BST性质不变。按*p的孩子数目分三种情况q行处理?br /><br /><strong>②删除*pl点的三U情?/strong><br />(1)*p是叶?卛_的孩子数?)<br />     无须q接*p的子树,只需?p的双?parent中指?p的指针域|空卛_?br /><br />(2)*p只有一个孩?child<br />     只需?child?p的双亲直接连接后Q即可删?p?br />  <font color="#ff0000">注意Q?/font><br />     *p既可能是*parent的左孩子也可能是其右孩子Q?child可能?p的左孩子或右孩子Q故共有4U状态?br />(3)*p有两个孩?br />     先oq=pQ将被删l点的地址保存在q中;然后?q的中序后l?pQƈ在查找过E中仍用parentC*p的双亲位|?q的中序后l?p一定是*q的右子树中最左下的结点,它无左子树。因此,可以删?q的操作{换ؓ删去?p的操作,卛_释放l点*p之前其数据复制?q中,q当于删去?q?br /><strong>③二叉排序树删除算?/strong> <font color="#ff00ff"><br /></font>分析Q?br />     上述三种情况都能l一到情?2)Q算法中只需针对情况(2)处理卛_?br />     注意边界条gQ若parent为空Q被删结?p是根Q故删去*p后,应将child|ؓ栏V?br /><br /><br />法Q删除关键字为key的结?<br />void DelBSTNode(BSTree *TptrQKeyType key)<br /> {<br />//在二叉排序树*Tptr中删d键字为key的结?br />  BSTNode *parent=NUllQ?p=*TptrQ?qQ?childQ?br />  while(p)<br /><strong>{ <br /></strong>     //从根开始查扑օ键字为key的待删结?br />    if(p->key==key) breakQ?/已找刎ͼ跛_查找循环<br />    parent=pQ?//parent指向*p的双?br />    p=(key<p->key)?p->lchildQp->rchildQ?//在关p的左或右子树中l找<br /><strong> }  <br />//注意Q也可以使用<strong>Z<font size="2">BOOL SearchBST(BiTree *TQKeyType keyQBiTree *fQBiTree &p)</font>的查扄?/strong><br />//l果?nbsp; parent 记录了要删除l点的父l点Qp指向要删除的l点<br /><br /></strong>      if(!p) returnQ?//找不到被删结点则q回<br />     q=pQ?//qC被删l点*p<br />     if(q->lchild && q->rchild) //*q的两个孩子均非空Q故?q的中序后l?p<br />    for(parent=qQp=q->rchildQ?p->lchildQ?parent=pQp=p=->lchild)Q?br />  //现在情况(3)已被转换为情?2)Q而情?1)相当于是情况(2)中child=NULL的状?br />    child=(p->lchild)?p->lchildQp->rchildQ?/若是情况(2)Q则child非空Q否则child为空<br />    if(!parent) //*p的双亲ؓI,说明*p为根Q删*p后应修改Ҏ?br />      *Tptr=childQ?//若是情况(1)Q则删去*p后,树ؓI;否则child变ؓ?br />    else{ //*p不是根,?p的孩子和*p的双亲进行连接,*p从树上被摘下<br />      if(p==parent->lchild) //*p是双亲的左孩?br />        parent->lchild=childQ?//*child作ؓ*parent的左孩子<br />      else parent->rchild=childQ?//*child作ؓ parent的右孩子<br />      if(p!=q) //是情?3)Q需?p的数据复制到*q<br />        q->key=p->keyQ?//若还有其它数据域亦需复制<br />     } //endif<br />    free(p)Q?/释放*p占用的空?br />  } //DelBSTNode<br /><strong>l出三种情况的不同算?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>W一U:</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 * DelNode(btree *p)<br />{<br />      if (p->lchild)<br />      {<br />            btree *r = p->lchild;   //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 />        while(r->rchild != 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 />        {<br />            r = r->rchild;<br />        }<br />            r->rchild = p->rchild;<br />            btree *q = p->lchild;   //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 />            free(p);<br />            return q;<br />      }<br />      else<br />      {<br />            btree *q = p->rchild;   //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 />            free(p);<br />            return q;<br />      }<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>W二U:</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 * DelNode(btree *p)<br />{<br />      if (p->lchild)<br />      {<br />            btree *r = p->lchild;   //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 />            btree *prer = p->lchild;   //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 />        while(r->rchild != 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 />        {<br />                  prer = r;<br />            r = r->rchild;<br />        }<br /><br />        if(prer != 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">的左孩子Q把</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 />        {<br />                  prer->rchild = r->lchild;<br />                  r->lchild = p->lchild; //</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">被删l点</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 />        r->rchild = p->rchild; //</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">被删l点</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 />            free(p);<br />            return r;<br />      }<br />      else<br />      {<br />            btree *q = p->rchild;   //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 />            free(p);<br />            return q;<br />      }<br />}<br style="mso-special-character: line-break" /><br style="mso-special-character: line-break" /></span><br /><br /></span></strong><img src ="http://www.shnenglu.com/Cass/aggbug/157397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Cass/" target="_blank">Yu_</a> 2011-10-03 10:07 <a href="http://www.shnenglu.com/Cass/archive/2011/10/03/157397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>哈夫曼树http://www.shnenglu.com/Cass/archive/2011/10/02/157353.htmlYu_Yu_Sun, 02 Oct 2011 09:04:00 GMThttp://www.shnenglu.com/Cass/archive/2011/10/02/157353.htmlhttp://www.shnenglu.com/Cass/comments/157353.htmlhttp://www.shnenglu.com/Cass/archive/2011/10/02/157353.html#Feedback0http://www.shnenglu.com/Cass/comments/commentRss/157353.htmlhttp://www.shnenglu.com/Cass/services/trackbacks/157353.html哈夫曼树定义为:l定n个权g为n个叶子结点,构造一二叉树Q若带权路径长度辑ֈ最,U这L二叉树ؓ最优二叉树Q也UCؓ哈夫曼树(Huffman tree)?br />1、那么什么是权?/span>Q什么是路径长度Q什么是?span style="color: red">权\径长?/span>呢?
权?/span>Q哈夫曼树的权值是自己定义的,他的物理意义表示数据出现的次数、频率。可以用树的每个l点数据域data存放一个特定的数表C它的倹{?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">

路径长度Q在一|中,从一个结点往下可以达到的孩子或子孙结点之间的通\Q称\径?span style="color: red">通\中分支的数目UCؓ路径长度。若规定根结点的层数?Q则从根l点到第L层结点的路径长度为L-1?br />
l点的带权\径长?/span>为:从根l点到该l点之间的\径长度与该结点的权的乘积?nbsp; 树中所有叶子节点的带权路径长度之和Q?span style="color: red">WPL=sigma(w*l)

2、哈夫曼树的构造过E。(l合图例Q?br />假设有n个权|则构造出的哈夫曼树有n个叶子结炏V?n个权值分别设?w1、w2?#8230;、wnQ则哈夫曼树的构造规则ؓQ?

  (1) w1、w2?#8230;Qwn看成是有n |的森?每棵树仅有一个结?Q?

  (2) 在森林中选出两个根结点的权值最的树合qӞ作ؓ一|树的左、右子树Q且新树的根l点权gؓ其左、右子树根结Ҏg和;

  (3)从森林中删除选取的两|Qƈ新树加入森林;

  (4)重复(2)?3)步,直到林中只剩一|为止Q该树即为所求得的哈夫曼?br />
3、哈夫曼树的应用Q哈夫曼~码Q前~~码Q?br />哈夫曼编?/strong>

在数据通信中,通常需要把要传送的文字转换为由二进制字W??l成的二q制Ԍq个q程被称之ؓ~码(Encoding)。例如,假设要传送的甉|为DCBBADDQ电文中只有A、B、C、D四种字符Q若q四个字W采用表(a)所C的~码ҎQ则甉|的代码ؓ11100101001111Q代码总长度ؓ14。若采用?b) 所C的~码ҎQ则甉|的代码ؓ0110101011100Q代码总长度ؓ13?/p>



字符集的不同~码Ҏ

哈夫曼树可用于构造总长度最短的~码Ҏ。具体构造方法如下:
N要编码的字符集ؓ{d1,d2,…,dn}Q各个字W在甉|中出现的ơ数或频率集合ؓ{w1,w2,…,wn}。以d1,d2,…,dn作ؓ叶子l点Q以w1,w2,…,wn作ؓ相应叶子l点的权值来构造一哈夫曼树。规定哈夫曼树中的左分支代表0Q右分支代表1Q则从根l点到叶子结Ҏl过的\径分支组成的0?的序列便l点对应字符的编码就是哈夫曼~码(Huffman Encoding)?/p>

在徏立不{长~码中,必须使Q何一个字W的~码都不是另一个编码的前缀Q这h能保证译码的唯一性。例如,若字WA的编码是00Q字WB的编码是001Q那么字WA的编码就成了字符B的编码的后缀。这P对于代码?01001Q在译码时就无法判定是将前两位码00译成字符Aq是前三位?01译成B。这L~码被称之ؓh二义性的~码Q二义性编码是不唯一的。而在哈夫曼树中,每个字符l点都是叶子l点Q它们不可能在根l点到其它字W结点的路径上,所以一个字W的哈夫曼编码不可能是另一个字W的哈夫曼编码的前缀Q从而保证了译码的非二义性?/p>

下图是甉|DCBBADD的哈夫曼树:



4、哈夫曼树的实现

由哈夫曼树的构造算法可知,用一个数l存攑֎来的n个叶子结点和构造过E中临时生成的结点,数组的大ؓ2n-1。所以,哈夫曼树cHuffmanTree中有两个成员字段Qdata数组用于存放l点QleafNum表示哈夫曼树叶子l点的数目。结Ҏ四个域,一个域weightQ用于存放该l点的权|一个域lChildQ用于存放该l点的左孩子l点在数l中的序P一个域rChildQ用于存放该l点的右孩子l点在数l中的序P一个域parentQ用于判定该l点是否已加入哈夫曼树中?/p>

哈夫曼树l点的结构ؓQ| 数据 | weight | lChild | rChild | parent |

     public class Node
    {
        char c; //存储的数据,Z个字W?br />        private double weight; //l点权?br />        private int lChild; //左孩子结?br />        private int rChild; //叛_子结?br />        private int parent; //父结?br />        //l点权值属?br />        public double Weight
        {
            get
            {
                return weight;
            }
            set
            {
                weight = value;
            }
        }
        //左孩子结点属?br />        public int LChild
        {
            get
            {
                return lChild;
            }
            set
            {
                lChild = value;
            }
        }
        //叛_子结点属?br />        public int RChild
        {
            get
            {
                return rChild;
            }
            set
            {
                rChild = value;
            }
        }
        //父结点属?br />        public int Parent
        {
            get
            {
                return parent;
            }
            set
            {
                parent = value;
            }
        }
        //构造器
        public Node()
        {
            weight = 0;
            lChild = -1;
            rChild = -1;
            parent = -1;
        }
        //构造器
        public Node(double weitht)
        {
            this.weight = weitht;
            lChild = -1;
            rChild = -1;
            parent = -1;
        }

        //构造器
        public Node(int w, int lc, int rc, int p)
        {
            weight = w;
            lChild = lc;
            rChild = rc;
            parent = p;
        }
    }

    public class HuffmanTree
    {
        private Node[] data; //l点数组
        private int leafNum; //叶子l点数目
        //索引?br />        public Node this[int index]
        {
            get
            {
                return data[index];
            }
            set
            {
                data[index] = value;
            }
        }
        //叶子l点数目属?br />        public int LeafNum
        {
            get
            {
                return leafNum;
            }
            set
            {
                leafNum = value;
            }
        }
        //构造器
        public HuffmanTree(int n)
        {
            data = new Node[2 * n - 1];
            leafNum = n;
        }
        //创徏哈夫曼树
        public void Create(Node[] datain)
        {
            double minL, minR;
            minL = minR = double.MaxValue;
            int lchild, rchild;
            lchild = rchild = -1;

            int length = data.Length;
            //初始化哈夫曼?br />            for (int i = 0; i < length; i++)
                data[i] = new Node();
            for (int i = 0; i < datain.Length; i++)
                data[i] = datain[i];

            //处理n个叶子结点,建立哈夫曼树
            for (int i = leafNum; i < length; i++)
            {
                //在全部结点中找权值最的两个l点
                for (int j = 0; j < i; j++)
                {
                    if (data[j].Parent == -1)
                    {
                        if (data[j].Weight < minL)
                        {
                            minR = minL;
                            minL = data[j].Weight;
                            rchild = lchild;
                            lchild = j;
                        }
                        else if (data[j].Weight < minR)
                        {
                            minR = data[j].Weight;
                            rchild = j;
                        }
                    }
                }
                data[lchild].Parent = data[rchild].Parent = i;
                data[i].Weight = minL + minR;
                data[i].LChild = lchild;
                data[i].RChild = rchild;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            HuffmanTree tree = new HuffmanTree(5);
            Node[] nodes = new Node[] { new Node(1), new Node(2), new Node(2.5d), new Node(3), new Node(2.6d) };
            tree.Create(nodes);

            Console.ReadLine();
        }
    }

/////////////////////////////节选自|络上的资料?/p>

Yu_ 2011-10-02 17:04 发表评论
]]>
优先队列http://www.shnenglu.com/Cass/archive/2011/10/02/157339.htmlYu_Yu_Sun, 02 Oct 2011 03:22:00 GMThttp://www.shnenglu.com/Cass/archive/2011/10/02/157339.htmlhttp://www.shnenglu.com/Cass/comments/157339.htmlhttp://www.shnenglu.com/Cass/archive/2011/10/02/157339.html#Feedback0http://www.shnenglu.com/Cass/comments/commentRss/157339.htmlhttp://www.shnenglu.com/Cass/services/trackbacks/157339.html最高优先权的元素。每个元素都有一个优先权或?br />/////用堆实现优先队列
1、把优先队列中的元素按优先大小l织成堆Q堆元素具有最大优先?br />2、优先队列的插入与删除可以用堆的插入与删除实现?br />3、优先队列在定义为priority_queue Q在STL?include<queue> 中实现?br /> priority_queue<int, vector<int>, greater<int> >qi2;

其中
W二个参Cؓ容器cd?br />W三个参Cؓ比较函数?br />




Yu_ 2011-10-02 11:22 发表评论
]]>
堆排?/title><link>http://www.shnenglu.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.shnenglu.com/Cass/archive/2011/10/01/157298.html</guid><wfw:comment>http://www.shnenglu.com/Cass/comments/157298.html</wfw:comment><comments>http://www.shnenglu.com/Cass/archive/2011/10/01/157298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Cass/comments/commentRss/157298.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Cass/services/trackbacks/157298.html</trackback:ping><description><![CDATA[估计q要问问Q什么是堆,什么是堆排序?堆与计算机分配内存的堆相同吗Q?br />很多资料l出Q堆的定义是<br />Q?Q、n个关键字序列QKlQK2Q?#8230;QKnQ称?Heap)Q当且仅当该序列满如下性质(UCؓ堆性质)Q?br />ki≤K2i且ki≤K2i+1 ?nbsp; Ki≥K2i且ki≥K2i+1 (1≤i≤ n) //ki相当于二叉树的非叶结点,K2i则是左孩子,k2i+1是右孩子 <br /><br /> <div id="akmosiq" class="spctrl"></div>Q?Q若此序列所存储的向量R[1..n]看做是一?strong>完全二叉?/strong>的存储结构,则堆实质上是满如下性质的完全二叉树Q? <div id="ekoasia" class="spctrl"></div>  <strong>树中M非叶l点的关键字均不大于(或不于)其左叛_?若存?l点的关键字?br /><br /></strong>Q?Q、根l点(亦称为堆?的关键字是堆里所有结点关键字?span style="color: red">最?/span>的堆UCؓ<span style="color: red">根?/span>Q又U最堆。根l点(亦称为堆?的关键字是堆里所有结点关键字?span style="color: red">最大?/span>Q称为大根堆Q又U?span style="color: red">最大堆?br /><br /></span><span>Q?Q、堆中Q一子树亦是堆?br />Q?Q、堆可以视ؓ一完全的二叉树,完全二叉树的一?#8220;优秀”的性质是,除了最底层之外Q每一层都是满的,q得堆可以利用</span><span style="color: #ff6600">数组</span><span>来表C(普通的一般的二叉树通常用链表作为基本容器表C)Q每一个结点对应数l中的一个元素?/span><br /><br />那么堆排序呢Q?br />堆排序其实就是将一l无序的序列变成堆的q程、下面我们一L看堆排序的算法?br />2、堆排序<br />以最大堆ZQ步骤ؓQ?br />  ① 先将初始文gR[1..n]建成一个大根堆,此堆为初始的无序? <div id="wmooggo" class="spctrl"></div>  ② 再将关键字最大的记录R[1](卛_?和无序区的最后一个记录R[n]交换Q由此得到新的无序区R[1..n-1]和有序区R[n]Q且满R[1..n-1].keys≤R[n].key <div id="sikqiqy" class="spctrl"></div>  ③׃交换后新的根R[1]可能q反堆性质Q故应将当前无序区R[1..n-1]调整为堆。然后再ơ将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换Q由此得到新的无序区R[1..n-2]和有序区R[n-1..n]Q且仍满_pR[1..n-2].keys≤R[n-1..n].keysQ同栯R[1..n-2]调整为堆? <div id="eeyamsi" class="spctrl"></div>  …… <div id="mceacki" 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 id="qmqsema" class="Apple-converted-space"> </span><br />一个无序的序列建成堆的q程实际上是一个反复筛选的q程。若此序列看作是一完全二叉树Q则最后一个非l端l点是[n/2](不大于n/2的整敎ͼQ因此筛选过E只需从[n/2]开始。要建成一个大堆Q即先选择一个值最大的元素q与序列中的最后一个元素交换,然后对序列前n-1元素q行{选,从新调整Z个大堆Q直到结束?span class="Apple-converted-space"> </span><br />法描述如下Q?span class="Apple-converted-space"> </span><br /> <span id="usuokyq" class="Apple-converted-space"> </span><br />typedef   int[]   Elem;//采用序存储表示完全二叉?span class="Apple-converted-space"> </span><br /><br />void   HeapAdjust(Elem   &e,int   s,int   m)<span id="uaewsyq" class="Apple-converted-space"> </span><br />{//e中s...m的元素除e[s]之外已经满堆的定义Qe[i] <=e[2*i]&&e[i] <=e[2*i+1]<span id="uawgsiy" class="Apple-converted-space"> </span><br />  //或e[i]> =e[2*i]&&e[i]> =e[2*i+1]),调整e[s]使的e[s...m]成ؓ一个大堆?span class="Apple-converted-space"> </span><br />      selem=e[s];<span id="sgkmgoe" class="Apple-converted-space"> </span><br />      for(i=2*s;i <=m;i*=2)//沿着D大的元素Q结点)向下{?span class="Apple-converted-space"> </span><br />      {<span id="mkyyuaq" class="Apple-converted-space"> </span><br />            if(i <m   &&   e[i] <e[i+1])++i;//i为D大的元素下标<span id="omoicks" class="Apple-converted-space"> </span><br />            if(selem> =e[i])break;<span id="kscoasi" class="Apple-converted-space"> </span><br />            e[s]=e[i];<span id="uieosyw" class="Apple-converted-space"> </span><br />            s=i;<span id="geymewu" class="Apple-converted-space"> </span><br />        }<span id="ukugcqg" class="Apple-converted-space"> </span><br />      e[s]=selem;<span id="oewquai" class="Apple-converted-space"> </span><br />}<span id="ieikewu" class="Apple-converted-space"> </span><br /><br />void   HeapSort(Elem   &e)<span id="iyscyoc" class="Apple-converted-space"> </span><br />{//寚w序表排序<span id="caeisqg" class="Apple-converted-space"> </span><br />    for(i=e.length/2;i> 0;--i)<span id="sqkeayo" class="Apple-converted-space"> </span><br />            HeapAdjust(e,i,e.length);<span id="qeycwwu" class="Apple-converted-space"> </span><br />    for(i=e.length;i> 1;--i)<span id="qgqcemm" class="Apple-converted-space"> </span><br />    {<span id="wmgykay" class="Apple-converted-space"> </span><br />          temp=e[1];                     //堆中的最后一个元素与W一个元素交?span class="Apple-converted-space"> </span><br />          e[1]=e[i];<span id="oeqkeck" class="Apple-converted-space"> </span><br />          e[i]=temp;<span id="kyswqge" class="Apple-converted-space"> </span><br />          HeapAdjust(H,1,i-1);//调整1..i-1的元素成为大堆<span id="qeysouk" class="Apple-converted-space"> </span><br />      }    <span id="goquoem" class="Apple-converted-space"> </span><br />}<br /><br /><br />/////////////////////////////////////////////////////////////<br />使用堆排序注意的问题Q:Q?br /></span></span>1、序列是?开始的。,注意定义QR[1..n]Q故要空出R[0]?br />2、堆排序法分ؓ两部分:建立大顶堆和排序?br />3、排序的最坏时间复杂度?strong>O(nlogn)</strong>。堆序的q_性能较接q于最坏性能?br />4、由于徏初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件? <div id="mcwqcai" class="spctrl"></div>5、 堆排序是地排序Q辅助空间ؓO(1)Q?它是<strong>不稳?/strong>的排序方法?br /><br />问题Q当序列I间为R[0,1....n]Q时Q该怎么M用堆排序呢?元素后移一位,q明显不是一个好Ҏ?img src ="http://www.shnenglu.com/Cass/aggbug/157298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Cass/" target="_blank">Yu_</a> 2011-10-01 16:55 <a href="http://www.shnenglu.com/Cass/archive/2011/10/01/157298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.517banjia.cn" target="_blank">þĻƷһ</a>| <a href="http://www.vip910.cn" target="_blank">97þ㽶߿ۿ</a>| <a href="http://www.kybdt.cn" target="_blank">˾ƷۺϾþþþ </a>| <a href="http://www.youk6.cn" target="_blank">þþɫۺϾɫ99</a>| <a href="http://www.phpluck.cn" target="_blank">þþƷ99þ㽶ɫ</a>| <a href="http://www.flycard.com.cn" target="_blank">AvƷþ</a>| <a href="http://www.cnshscj.cn" target="_blank">ҹƷþþþþþ</a>| <a href="http://www.lubricantbrand.cn" target="_blank">պŷþ</a>| <a href="http://www.sbznw.cn" target="_blank">þ</a>| <a href="http://www.vcdordvd.cn" target="_blank">aѹۿþav</a>| <a href="http://www.chenxipeng.cn" target="_blank">޾þһ</a>| <a href="http://www.ilovegou.cn" target="_blank">޾ƷŮþþþ99С˵</a>| <a href="http://www.po18h.cn" target="_blank">ɫþþþSWAGƷ</a>| <a href="http://www.lftdly.cn" target="_blank">þþҹƷ</a>| <a href="http://www.gocq8.cn" target="_blank">޹Ʒþþϼ2</a>| <a href="http://www.hefxxw.cn" target="_blank">þùƷþþ</a>| <a href="http://www.tdstudio.com.cn" target="_blank">99þþƷѿ</a>| <a href="http://www.sixyin.cn" target="_blank">þþƷ99þþ㽶</a>| <a href="http://www.jiansuj.cn" target="_blank">þþþþþþþþ</a>| <a href="http://www.gbpa.cn" target="_blank">vaþþþúݺ</a>| <a href="http://www.92kv.cn" target="_blank">97þþƷ</a>| <a href="http://www.zzhysh.cn" target="_blank">Ʒþþþþù</a>| <a href="http://www.jsxtcmss.cn" target="_blank">ĻþþƷ</a>| <a href="http://www.yozang.cn" target="_blank">þۺ</a>| <a href="http://www.yixue77.cn" target="_blank">þþѹ۳ӰԺ</a>| <a href="http://www.huanheng.com.cn" target="_blank">99þɫĻ</a>| <a href="http://www.mdz8.cn" target="_blank">www.þ.com</a>| <a href="http://www.52yydy.cn" target="_blank">þҹɫƷa</a>| <a href="http://www.kunow.cn" target="_blank">һɫþHEZYO</a>| <a href="http://www.bfav.cn" target="_blank">66ƷۺϾþþþþþ</a>| <a href="http://www.ttpcom.com.cn" target="_blank">޾Ʒھþ</a>| <a href="http://www.wd12cjf8.cn" target="_blank">Ʒþþþþþþҹ</a>| <a href="http://www.uzxin.cn" target="_blank">þþþ97Һ</a>| <a href="http://www.tianyacity.cn" target="_blank">vaĻþò </a>| <a href="http://www.oulihong.cn" target="_blank">þþþþƷAV</a>| <a href="http://www.yangfenghua.cn" target="_blank">ŷ츾BBBþþ</a>| <a href="http://www.tjjobs.com.cn" target="_blank">˾þav</a>| <a href="http://www.1118.org.cn" target="_blank">þ޹vwww </a>| <a href="http://www.popotang.cn" target="_blank">þѾƷav</a>| <a href="http://www.facpw.cn" target="_blank">þ99ۺϾƷҳ</a>| <a href="http://www.tmqywedding.cn" target="_blank">ŷҹƷþþþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>