如题 自用笔记 如有错误欢迎及时指正
面对仅仅知道先序序列(DLR)求后序序列(LRD),首先想到的是不可能,若对一般的二叉树而言确实无法做到,但是满二叉树的特殊性使得该命题成立!下面给出本文所用例子。
思路:满二叉树左右子树结点个数相同且总节点数为奇数个, 只要能确定根节点就可以确定LRD序列,而DLR序列可以让我们知道根节点。采用递归方法完成该问题。
递归模型:
设DLR序列存在pre[l1…h1]中 LRD序列求出后保存到post[l2…h2]中,由先序序列第一个结点是根节点,可以定位后序序列中最后一个结点(根节点),剩下部分对半划分,递归进入。
case1.
f(pre[],l1,h1,post[],l2,h2) 无操作 l1>h1或l2>h2时
case2.
f(pre[],l1,h1,post[],l2,h2) post[h2]=pre[l1] 其他情况时
1.划分,求出pre[l1…h1]的中间元素,定出左右子树
half=(h1-l1)/2
2.先序序列pre[l1…h1]中左子树为pre[l1+1…l1+half],
将其放入后序序列post[l2…h2]中左子树部分post[l2…l2+half-1]中
f(pre[],l1+1,l1+half,post[],l2,l2+half-1)
3.先序序列pre[l1…h1]中右子树为pre[half+l1+1…h1],
将其放入后序序列post[l2…h2]中右子树部分post[l2+half…h2-1]中。
f(pre[],half+l1+1,h1,post[],l2+half,h2-1)
可运行代码
#include<stdio.h>
typedef int DataType;
void DLRtoLRD(DataType pre[],int l1,int h1,DataType post[],int l2,int h2){
int half; //pre保存先序序列 l1...h1为下标范围,post同理;half用于划分先序序列下左右子树;
if(l1>h1){
return;
}else{
post[h2] = pre[l1]; //将先序序列的元素放入后序序列对应位置,首次运行时体现为先序序列首节点(根节点)位置放入后续序列尾节点(根节点)位置
half = (h1 - l1) / 2;
DLRtoLRD(pre,l1+1,l1+half,post,l2,l2+half-1);
DLRtoLRD(pre,half+l1+1,h1,post,l2+half,h2-1);
}
}//DLRtoLRD
void print(DataType print[], int len_print)
{ //输出函数
for (int k = 0; k < len_print; k++)
{
printf("%d ", print[k]);
}
printf("\n");
}
int main(){
DataType pre[7] = {1,2,4,5,3,6,7}; //先序序列
DataType post[7]={0};
printf("先序序列:");
print(pre, 7);
DLRtoLRD(pre, 0, 6, post, 0, 6);
printf("后序序列:");
print(post, 7);
return 0;
}
以上
2021.10.17
00:15