1.完全二叉树的最后一个结点的编号是n,则它的父结点的编号为[n/2],则叶子结点个数为n-[n/2]。 结点数为奇数,所以度为1的结点有0个;所以非空左子树为0;非空右子树为0;
完全二叉树的最后一个结点的编号一定是1001,则它的父结点的编号为1001/2=500,则叶子结点个数为1001-500=501.非空左子树为0;非空右子树为0;
2.结点数为奇数,所以度为1的结点有0个,度为2的节点数=度为0的节点数-1,所以2*度为0的节点数-1 = 1001,所以度为0的节点数为501
n0 = n2 + 1,代入n0 + n1 + n2 = 1001得到2n2 + 1+ n1 = 1001, n1只能是0或者1,为满足2n2 + 1 + n1 = 1001,必须n1 =0,因此n2 = 500,所以n0 = 501,即叶子个数是501个
思路: 1)后序遍历的最后一位即是二叉树的根节点。 2)然后再中序遍历找到根结点,根节点左边的所有序列便是左子树的中序遍历结果,右边的所有序列便是右子树中序遍历结果。 3)在后序遍历中找到对应的左子树,右子树。 4)在左右子树的先序和中序结果中继续重复1 , 2 ,3步骤,便可还原二叉树。 如下图:
先序遍历:根 —> 左 —> 右
中序遍历:左 —> 根 —> 右
后序遍历:左 —> 右 —>根
算法思想: 根据先序遍历的特点,第一个遍历的结点就是根结点,我们找到根结点
根据中序遍历的特点,我们知道此根结点左边的序列为左子树,根结点右侧的序列为右子树
根据原始的先序和中序遍历结果,得到左右子树的先序和中序遍历结果,递归还原二叉树
根据遍历结果构造子树的遍历结果: 后序遍历:[ [ 左子树后序遍历结果 ],[ 右子树后序遍历结果 ],根节点] 中序遍历:[[ 左子树中序遍历结果 ],根节点,[ 右子树中序遍历结果 ]]举例:
preorder = [3,9,20,15,7] inorder = [9,3,15,20,7]
首先我们根据preorder知道结点3为整个树的根结点,然后根据inorder序列知道3左侧的序列[9]为左子树,右侧的序列[15,20,7]为右子树,就像这样
接下来我们构造左右子树的先序和中序遍历序列:
left_preorder = [9] right_preorder = [20,15,7]
left_inorder = [9] right_inorder = [15,20,7]
接下来就是递归的过程了。按照同样的步骤,根据preorder序列的第一个元素得到根结点,根据得到的这个根结点以及inorder得到左右子树,就像这样:2
#include#include #include using namespace std; struct Node{ char data; Node* left; Node* right; Node(char data){ this->data = data; this->left = nullptr; this->right = nullptr; } }; vector getCharArray(string str){ vector res; for(char c : str){ res.push_back(c); } return res; } Node* getTree(vector & preOrder, vector & inOrder){ if(preOrder.empty()){ return nullptr; } Node* root = new Node(preOrder[0]);//构造根结点 vector ::iterator mid = find(inOrder.begin(), inOrder.end(), preOrder[0]); int left_nodes = mid - inOrder.begin(); vector left_inOrder(inOrder.begin(), mid); vector right_inOrder(mid+1, inOrder.end()); vector left_preOrder(preOrder.begin()+1, preOrder.begin()+1+left_nodes); vector right_preOrder(preOrder.begin()+1+left_nodes, preOrder.end()); root->left = getTree(left_preOrder, left_inOrder); root->right = getTree(right_preOrder, right_inOrder); return root; } void postOrder(Node* root){ if(root == nullptr){ return ; } postOrder(root->left); postOrder(root->right); cout< data; } int main(){ string pre_str; string in_str; while(cin >> pre_str >> in_str){ vector preOrder = getCharArray(pre_str); vector inOrder = getCharArray(in_str); Node* root = getTree(preOrder, inOrder); postOrder(root); cout< 关于层次序列和中序序列还原二叉树的方式
就是使用层次序列找到根节点,在通过中序序列找到左右子树的分布,再通过左右子树和层次序列,再找到根节点,再通过同样的方式来操作。