普通的二叉树知道前序遍历序列或后序遍历序列和中序遍历序列后可以转换为另一种遍历序列,根据前序或后序遍历序列找根,再根据中序遍历序列划分左右子树,再获取左子树和右子树的根。
但二叉排序树比较特殊,因为二叉排序树的特性(左子树的所有结点的值小于根结点的值,右子树的所有结点的值大于等于根结点的值),所以可以直接根据前序序列转换为后序序列,反之亦然。
先序序列转后序序列:
首先分解求后序遍历结果的过程:
-
求出左子树的后序遍历结果
-
求出右子树后序遍历的结果
-
将当前子树的根节点加入后序遍历的结果中去
void getPost(int root, int tail){// 求由 root 到 tail 这段区间表示的树的后序遍历结果 if (root > tail)//区间不存在 return; int i = root + 1;//根节点的下一个节点 int j = tail; while (i <= tail && pre[root] > pre[i]) i++;//从左往右寻找第一个大于根节点的位置,即右子树的根节点(从i到tail表示右子树) while (j > root && pre[root] <= pre[j]) j--;//从右往左寻找第一个小于等于根节点的位置,即左节点的结束位置(从root到j表示左子树) if (i - j != 1) return;//如果该序列合法的话i一定是比j大1的。 getPost(root + 1, j); //1 getPost(i, tail);//2 post.push_back(pre[root]);//3 }
后序序列转先序序列:首先分解求后序遍历结果的过程: 1.将当前子树的根节点加入先序遍历的结果中去 2.求出左子树的先序遍历结果 3.求出右子树先序遍历的结果
-
#include<iostream> #include<vector> using namespace std; vector<int> pre, post; void getPre(int start, int root){ if (start > root) return; int i = root - 1; int j = start; while (i >= start && post[i] >= post[root]) i--; while (j < root && post[j] < post[root]) j++; if (j - i != 1) return; pre.push_back(post[root]);//根 getPre(start, i);//左 getPre(j, root - 1);//右 } int main(){ int n; cin >> n; post.resize(n); for (int i = 0; i < n; i++) cin >> post[i]; getPre(0, n - 1); for (int i = 0; i < pre.size(); i++) cout << pre[i] << " "; return 0; }