Algorithm 前序到后序遍历
如果二叉搜索树的预序遍历是6、2、1、4、3、7、10、9、11,如何获得后序遍历?预序=按当前节点、左子树、右子树的顺序输出二叉树的值 Post order=按左子树、右子树和当前节点的顺序输出二叉树的值 在二叉搜索树中,左子树中所有节点的值都小于当前节点的值;对于正确的子树也是如此。因此,如果知道二叉搜索树的预排序转储的开始(即其根节点的值),则可以轻松地将整个转储分解为根节点值、左子树节点的值和右子树节点的值Algorithm 前序到后序遍历,algorithm,data-structures,tree-traversal,binary-search-tree,Algorithm,Data Structures,Tree Traversal,Binary Search Tree,如果二叉搜索树的预序遍历是6、2、1、4、3、7、10、9、11,如何获得后序遍历?预序=按当前节点、左子树、右子树的顺序输出二叉树的值 Post order=按左子树、右子树和当前节点的顺序输出二叉树的值 在二叉搜索树中,左子树中所有节点的值都小于当前节点的值;对于正确的子树也是如此。因此,如果知道二叉搜索树的预排序转储的开始(即其根节点的值),则可以轻松地将整个转储分解为根节点值、左子树节点的值和右子树节点的值 要按后序输出树,将应用递归和输出重新排序。此任务留给读者。您将获得树的预顺序遍历
要按后序输出树,将应用递归和输出重新排序。此任务留给读者。您将获得树的预顺序遍历,它是通过以下操作构建的:输出、左遍历、右遍历 由于后序遍历来自BST,因此可以通过对数字进行排序,从后序遍历中推断顺序遍历(左遍历、输出遍历、右遍历)。在您的示例中,顺序遍历是1、2、3、4、6、7、9、10、11 通过两次遍历,我们可以构造原始树。让我们使用一个更简单的例子:
- 预购:2,1,4,3
- 顺序:1、2、3、4
2
/ \
1 4
/
3
使用树结构,我们可以通过遍历树来获得后序遍历:左遍历、右遍历、输出。对于本例,后序遍历是1、3、4、2
要推广该算法,请执行以下操作:
使用上述算法,与问题中的前序遍历关联的后序遍历是:1、3、4、2、9、11、10、7、6。到达那里只是一种练习。基于昂德雷·图尼的回答。仅对BST有效
例如:
20
/ \
10 30
/\ \
6 15 35
预订单=201061535邮政=61510353020 对于BST,在前序遍历中;数组的第一个元素是20。这是我们树的根。数组中小于20的所有数字形成其左子树,大于20的数字形成右子树
//N = number of nodes in BST (size of traversal array)
int post[N] = {0};
int i =0;
void PretoPost(int pre[],int l,int r){
if(l==r){post[i++] = pre[l]; return;}
//pre[l] is root
//Divide array in lesser numbers and greater numbers and then call this function on them recursively
for(int j=l+1;j<=r;j++)
if(pre[j]>pre[l])
break;
PretoPost(a,l+1,j-1); // add left node
PretoPost(a,j,r); //add right node
//root should go in the end
post[i++] = pre[l];
return;
}
//N=BST中的节点数(遍历数组的大小)
int post[N]={0};
int i=0;
无效预结算(int pre[],int l,int r){
if(l==r){post[i++]=pre[l];return;}
//pre[l]是根
//将数组分为较小的数和较大的数,然后递归调用此函数
对于(int j=l+1;jpre[l])
打破
PretoPost(a,l+1,j-1);//添加左节点
PretoPost(a,j,r);//添加右节点
//根最终应该消失
post[i++]=pre[l];
返回;
}
如果有任何错误,请更正。您将获得预排序遍历结果。然后将值放入合适的二叉搜索树中,只需按照获得的BST的后序遍历算法进行操作。我知道这很旧,但有更好的解决方案 我们不必重建BST来从预订单中获取后订单 下面是一个递归执行此操作的简单python代码:
import itertools
def postorder(preorder):
if not preorder:
return []
else:
root = preorder[0]
left = list(itertools.takewhile(lambda x: x < root, preorder[1:]))
right = preorder[len(left) + 1:]
return postorder(left) + postorder(right) + [root]
if __name__ == '__main__':
preorder = [20, 10, 6, 15, 30, 35]
print(postorder(preorder))
说明:
我们知道我们是在预定。这意味着根位于BST中值列表的索引0
。我们知道根后面的元素是:
- 第一:小于
的元素,它们属于根的左子树根
- 第二:大于
根的元素,它们属于根的右子树
然后,我们只需递归调用两个子树上的函数(仍然是预序),然后调用chain
left+right+root
(即后序)。如果您已获得预序,并且希望将其转换为后序。然后你应该记住,在BST中,顺序总是以升序给出数字。因此,你既有顺序也有前序来构造一棵树
前序:6,2,1,4,3,7,10,9,11
顺序:1,2,3,4,6,7,9,10,11
及其后序:
1 3 4 2 9 11 10 7 6
这里以数组形式给出了二叉搜索树的前序遍历。
因此,预排序数组的第一个元素将是BST的根。我们将找到BST的左部分和BST的右部分。预排序数组中的所有元素小于根将是左节点,预排序数组中的所有元素大于根将是右节点
#include <bits/stdc++.h>
using namespace std;
int arr[1002];
int no_ans = 0;
int n = 1000;
int ans[1002] ;
int k = 0;
int find_ind(int l,int r,int x){
int index = -1;
for(int i = l;i<=r;i++){
if(x<arr[i]){
index = i;
break;
}
}
if(index == -1)return index;
for(int i =l+1;i<index;i++){
if(arr[i] > x){
no_ans = 1;
return index;
}
}
for(int i = index;i<=r;i++){
if(arr[i]<x){
no_ans = 1;
return index;
}
}
return index;
}
void postorder(int l ,int r){
if(l < 0 || r >= n || l >r ) return;
ans[k++] = arr[l];
if(l==r) return;
int index = find_ind(l+1,r,arr[l]);
if(no_ans){
return;
}
if(index!=-1){
postorder(index,r);
postorder(l+1,index-1);
}
else{
postorder(l+1,r);
}
}
int main(void){
int t;
scanf("%d",&t);
while(t--){
no_ans = 0;
int n ;
scanf("%d",&n);
for(int i = 0;i<n;i++){
cin>>arr[i];
}
postorder(0,n-1);
if(no_ans){
cout<<"NO"<<endl;
}
else{
for(int i =n-1;i>=0;i--){
cout<<ans[i]<<" ";
}
cout<<endl;
}
}
return 0;
}
#包括
使用名称空间std;
int-arr[1002];
int no_ans=0;
int n=1000;
int ans[1002];
int k=0;
int find_ind(int l,int r,int x){
int指数=-1;
对于(inti=l;i我们知道,前序跟随父、左、右序列
我
#include <bits/stdc++.h>
using namespace std;
int arr[1002];
int no_ans = 0;
int n = 1000;
int ans[1002] ;
int k = 0;
int find_ind(int l,int r,int x){
int index = -1;
for(int i = l;i<=r;i++){
if(x<arr[i]){
index = i;
break;
}
}
if(index == -1)return index;
for(int i =l+1;i<index;i++){
if(arr[i] > x){
no_ans = 1;
return index;
}
}
for(int i = index;i<=r;i++){
if(arr[i]<x){
no_ans = 1;
return index;
}
}
return index;
}
void postorder(int l ,int r){
if(l < 0 || r >= n || l >r ) return;
ans[k++] = arr[l];
if(l==r) return;
int index = find_ind(l+1,r,arr[l]);
if(no_ans){
return;
}
if(index!=-1){
postorder(index,r);
postorder(l+1,index-1);
}
else{
postorder(l+1,r);
}
}
int main(void){
int t;
scanf("%d",&t);
while(t--){
no_ans = 0;
int n ;
scanf("%d",&n);
for(int i = 0;i<n;i++){
cin>>arr[i];
}
postorder(0,n-1);
if(no_ans){
cout<<"NO"<<endl;
}
else{
for(int i =n-1;i>=0;i--){
cout<<ans[i]<<" ";
}
cout<<endl;
}
}
return 0;
}
6
/ \
2 7
/ \ \
1 4 10
/ / \
3 9 11
def postorder(root):
if root==None:
return
postorder(root.left)
print(root.data,end=" ")
postorder(root.right)
def preordertoposorder(a,n):
root=Node(a[0])
top=Node(0)
temp=Node(0)
temp=None
stack=[]
stack.append(root)
for i in range(1,len(a)):
while len(stack)!=0 and a[i]>stack[-1].data:
temp=stack.pop()
if temp!=None:
temp.right=Node(a[i])
stack.append(temp.right)
else:
stack[-1].left=Node(a[i])
stack.append(stack[-1].left)
return root
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
a=[40,30,35,80,100]
n=5
root=preordertoposorder(a,n)
postorder(root)
# print(root.data)
# print(root.left.data)
# print(root.right.data)
# print(root.left.right.data)
# print(root.right.right.data)
class Tree:
def __init__(self, data = None):
self.left = None
self.right = None
self.data = data
def add(self, data):
if self.data is None:
self.data = data
else:
if data < self.data:
if self.left is None:
self.left = Tree(data)
else:
self.left.add(data)
elif data > self.data:
if self.right is None:
self.right = Tree(data)
else:
self.right.add(data)
def inOrder(self):
if self.data:
if self.left is not None:
self.left.inOrder()
print(self.data)
if self.right is not None:
self.right.inOrder()
def postOrder(self):
if self.data:
if self.left is not None:
self.left.postOrder()
if self.right is not None:
self.right.postOrder()
print(self.data)
def preOrder(self):
if self.data:
print(self.data)
if self.left is not None:
self.left.preOrder()
if self.right is not None:
self.right.preOrder()
arr = [6, 2, 1, 4, 3, 7, 10, 9, 11]
root = Tree()
for i in range(len(arr)):
root.add(arr[i])
print(root.inOrder())
6
/ \
/ \
/ \
/ \
{1,2,3,4} {7,9,10,11}
6
/ \
/ \
/ \
/ \
2 {7,9,10,11}
/ \
/ \
/ \
1 {3,4}
6
/ \
/ \
/ \
/ \
2 {7,9,10,11}
/ \
/ \
/ \
1 4
/
3
6
/ \
/ \
/ \
/ \
2 7
/ \ \
/ \ {9,10,11}
/ \
1 4
/
3
6
/ \
/ \
/ \
/ \
2 7
/ \ \
/ \ 10
/ \ / \
1 4 9 11
/
3