<TABLE cellPadding=5 width="90%" border=0><TR><TD width="100%" bgColor=#e0e0e0>< 5px; MARGIN-BOTTOM: 5px"><B>函数</B> Left_Child(v,T);</P>< 5px; MARGIN-BOTTOM: 5px"><B>功能</B></P><BLOCKQUOTE>< 5px; MARGIN-BOTTOM: 5px">这是一个求左儿子结点的函数。函数值为树T中结点v的左儿子。当结点v没有左儿子时,函数值为∧。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>实现</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">Function Left_Child(v:TPosition;var T:TreeType):TPosition;</P><P 5px; MARGIN-BOTTOM: 5px">begin</P><P 5px; MARGIN-BOTTOM: 5px"> if (2*v>T.NodeCount)or(T.NodeList[2*v]=&) then return(0)</P><P 5px; MARGIN-BOTTOM: 5px"> else return(2*v);</P><P 5px; MARGIN-BOTTOM: 5px">end;</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>说明</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">如果结点v的左儿子存在,则其下标为2*v。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>复杂性</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">显然为<I>O</I>(1)。</P></BLOCKQUOTE></TD></TR><TR><TD width="100%" bgColor=#e0e0e0><P 5px; MARGIN-BOTTOM: 5px"><B>函数</B> Right_Child(v,T);</P><P 5px; MARGIN-BOTTOM: 5px"><B>功能</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">这是一个求右儿子结点的函数。函数值为树T中结点v的右儿子。当结点v没有右儿子时,函数值为∧。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>实现</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">Procedure Right_Child(v:TPosition;var T:TreeType):TPosition;</P><P 5px; MARGIN-BOTTOM: 5px">begin</P><P 5px; MARGIN-BOTTOM: 5px"> if (2*v+1>T.NodeCount)or(T.NodeList[2*v+1]=&) then return(0)</P><P 5px; MARGIN-BOTTOM: 5px"> else return(2*v+1);</P><P 5px; MARGIN-BOTTOM: 5px">end;</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>说明</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">如果结点v的左儿子存在,则其下标为2*v+1。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>复杂性</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">显然为<I>O</I>(1)。</P></BLOCKQUOTE></TD></TR><TR><TD width="100%" bgColor=#e0e0e0><P 5px; MARGIN-BOTTOM: 5px"><B>函数</B> Create(x,Left,Right,T);</P><P 5px; MARGIN-BOTTOM: 5px"><B>功能</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">这是一个建树过程。该函数生成一棵新的二叉树T,T的根结点标号为x,左右儿子分别为Left和Right。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>实现</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">Procedure Create(x abelType;var Left,Right,T:TreeType);</P><P 5px; MARGIN-BOTTOM: 5px">begin</P><P 5px; MARGIN-BOTTOM: 5px"> T.NodeList[1]:=x;</P><P 5px; MARGIN-BOTTOM: 5px"> T.NodeCount:=Left.NodeCount+Right.NodeCount+1;</P><P 5px; MARGIN-BOTTOM: 5px"> h_left:=cal(Left.NodeCount);</P><P 5px; MARGIN-BOTTOM: 5px"> h_right:=cal(Right.NodeCount);{分别计算Left和Right的高度}</P><P 5px; MARGIN-BOTTOM: 5px"> if h_left>h_Right then h:=h_left else h:=h_right;{新树T的高度为h+1}</P><P 5px; MARGIN-BOTTOM: 5px"> for i:=Left.NodeCount+1 to (1 shl (h+1))-1 do Left.NodeList:=&;</P><P 5px; MARGIN-BOTTOM: 5px"> Left.NodeCount:=(1 shl (h+1))-1;</P><P 5px; MARGIN-BOTTOM: 5px"> {将Left补成高度为h的满二叉树;其中shl是左移位运算,用来计算2的幂}</P><P 5px; MARGIN-BOTTOM: 5px">if h_right<h then</P><P 5px; MARGIN-BOTTOM: 5px"> begin</P><P 5px; MARGIN-BOTTOM: 5px"> for i:=Right.NodeCount+1 to (1 shl h)-1 do Right.NodeList:=&;</P><P 5px; MARGIN-BOTTOM: 5px"> Right.NodeCount:=(1 shl h)-1;</P><P 5px; MARGIN-BOTTOM: 5px"> end;</P><P 5px; MARGIN-BOTTOM: 5px"> {若Right的高度小于h,则将Right补成高度为h-1的满二叉树}</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px">{=======</P><P 5px; MARGIN-BOTTOM: 5px">对于Left中编号为i的结点v,它在新树T中的编号为2<SUP>h </SUP>+i,其中h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> ;对于Right中编号为i的结点v,它在新树T中的编号为2<SUP>h+1</SUP>+i,其中h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> 。</P><P 5px; MARGIN-BOTTOM: 5px">=======}</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px"> for i:=1 to Left.NodeCount do</P><P 5px; MARGIN-BOTTOM: 5px"> T.NodeList[(1 shl cal(i))+i]:=Left.NodeList;</P><P 5px; MARGIN-BOTTOM: 5px">{计算出Left中编号为i的结点在T中的位置,将其复制到T中}</P><P 5px; MARGIN-BOTTOM: 5px"> for i:=1 to Right.NodeCount do</P><P 5px; MARGIN-BOTTOM: 5px"> T.NodeList[(1 shl (cal(i)+1))+i]:=Right.NodeList;</P><P 5px; MARGIN-BOTTOM: 5px">{计算出Right中编号为i的结点在T中的位置,将其复制到T中}</P><P 5px; MARGIN-BOTTOM: 5px">end;</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px">其中cal(i)用来计算含有i个结点的近似满二叉树T的高度,cal(i)=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif">,可以实现如下:</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px">Function cal(i:integer;):integer;</P><P 5px; MARGIN-BOTTOM: 5px">var</P><P 5px; MARGIN-BOTTOM: 5px">x:real;</P><P 5px; MARGIN-BOTTOM: 5px">begin</P><P 5px; MARGIN-BOTTOM: 5px"> x:=log2(i+1)-1;</P><P 5px; MARGIN-BOTTOM: 5px"> if x=int(x) then return(x) else return(int(x)+1); {向上取整}</P><P 5px; MARGIN-BOTTOM: 5px">end;</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px">其中log2(n)计算实数n以2为底的对数。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>说明</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px">在顺序存储的结构下,建立一棵新的二叉树的过程比较复杂。我们首先给出以下几个命题:</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px"><B>命题一</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">一棵<a href="http://algorithm.myrice.com/datastructure/basic/tree/chapter2.htm" target="_blank" >高度</A>为h的<a href="http://algorithm.myrice.com/datastructure/basic/binary_tree/chapter3.htm" target="_blank" >满二叉树</A>有2<SUP>h+1</SUP>-1个结点。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">证明:</P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">满二叉树的第i层有2<SUP>i</SUP>个结点,i=0,1,2,...,h(树根为第0层),因此高度为h的满二叉树有2<SUP>0</SUP>+2<SUP>1</SUP>+..+2<SUP>h </SUP>= 2<SUP>h+1</SUP>-1个结点。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>推论一</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">我们从树根起,自上层到下层,逐层从左到右给二叉树的所有结点编号,如<a href="http://algorithm.myrice.com/datastructure/basic/binary_tree/chapter5_1.htm#image6" target="_blank" >图6</A>所示,则<a href="http://algorithm.myrice.com/datastructure/basic/binary_tree/chapter3.htm" target="_blank" >近似满二叉树</A>的第h层的从左到右第k个结点的编号为2<SUP>h</SUP>+k-1。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">证明:</P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">由于是近似满二叉树,所以第0层到第h-1层是满二叉树,根据命题一知道共有2<SUP>h</SUP>-1个结点,因此第h层的从左到右第1个结点的编号为2<SUP>h</SUP>-1+1,第h层的从左到右第k个结点的编号为2<SUP>h</SUP>-1+k。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>推论二</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">一棵有n个结点的近似满二叉树,高度为<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(n+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> ,其中<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif"> <img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif">是天花板符号,<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif"> x<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif">表示大于等于x的最小整数。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">证明:</P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">有n个结点的近似满二叉树,若其高度为h,则满足2<SUP>h</SUP>-1<n≤2<SUP>h+1</SUP>-1,化简得 log<SUB>2</SUB>(n+1)-1 ≤ h < [log<SUB>2</SUB>(n+1)-1]+1,即h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(n+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif">。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>推论三</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">在近似满二叉树T中,设编号为i的结点处于T的第h层从左到右第k个位置上,则h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> ,k=i-(2<SUP>h</SUP>-1)。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">证明:</P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">我们先不考虑编号大于i的结点,则前i个结点构成一棵近似满二叉树,根据推论二知其层数为h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> ,又因为第0层到第h-1层是满二叉树,根据命题一知道共有2<SUP>h</SUP>-1个结点,所以编号为i的结点处于第h层的第k=i-(2<SUP>h</SUP>-1)个位置上。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">我们用T(h,k)表示树T的第h层的第k个结点,则有下列命题:</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px"><B>命题二</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">Left(h,k)=T(h+1,k),Right(h,k)=T(h+1,k+2<SUP>h</SUP>),其中Left和Right分别是树T的根结点的左右子树。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">证明:</P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">显然。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">我们用N(v,T)表示结点v在生成的新树T中的编号,则有下列命题:</P><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px"><B>命题三</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">对于Left中编号为i的结点v,N(v,T)=2<SUP>h </SUP>+i,其中h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> ;对于Right中编号为i的结点v,N(v,T)=2<SUP>h+1</SUP>+i,其中h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> 。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">证明:</P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">在Left中编号为i的结点,根据推论三,他处于Left的第h=<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img10.gif">log<SUB>2</SUB>(i+1)-1<img src="http://algorithm.myrice.com/datastructure/basic/binary_tree/images/img11.gif"> 层,第k=i-(2<SUP>h</SUP>-1)个位置上。根据命题二该结点处于新树T的第h+1层第k个位置上,所以根据推论一,它在二叉树T中的编号为2<SUP>h+1</SUP>+k-1=2*2<SUP>h</SUP>+[i-(2<SUP>h</SUP>-1)]-1=2<SUP>h</SUP>+i。结点在Right中的情况同理可证。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"> </P><P 5px; MARGIN-BOTTOM: 5px">有了命题三,我们就可以完成建树的过程。算法如下:</P><OL><LI><P 5px; MARGIN-BOTTOM: 5px">根据推论二计算Left和Right的高度,分别为h<SUB>Left</SUB>和h<SUB>Right </SUB>; </P><LI><P 5px; MARGIN-BOTTOM: 5px">设h=max{h<SUB>Left</SUB>,h<SUB>Right</SUB>},新树T的高度就为h+1; </P><LI><P 5px; MARGIN-BOTTOM: 5px">将Left补成高度为h的满二叉树; </P><LI><P 5px; MARGIN-BOTTOM: 5px">若h<SUB>Right</SUB><h,则将Right补成高度为h-1的满二叉树; </P><LI><P 5px; MARGIN-BOTTOM: 5px">依次扫描Left的每一个结点,根据命题三计算出Left中编号为i的结点在T中的位置,将其复制到T中; </P><LI><P 5px; MARGIN-BOTTOM: 5px">依次扫描Right的每一个结点,根据命题三计算出Right中编号为i的结点在T中的位置,将其复制到T中; </P></LI></OL><P 5px; MARGIN-BOTTOM: 5px">具体程序见前文的实现。</P></BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px"><B>复杂性</B></P><BLOCKQUOTE><P 5px; MARGIN-BOTTOM: 5px">算法的主要时间花在扫描和赋值结点上,设新树有n个结点,则复杂性为<I>O</I>(n)。</P></BLOCKQUOTE></TD></TR></TABLE> |