剑指Offer

xiaoxiao2021-02-28  78

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都 互不相同 分析:二叉搜索树即二叉排序树,根节点左子树小于根,右子树大于根。以往和二叉树有关的题目都是设计前序、中序,或者中序后序,或者中序层序,因为要还原二叉树中序不可获取。但是二叉搜索树是比较特殊,因为其本身的性质,会导致后序、前序、中序有规律。 如:                         8                      6                 10              5            7       9            11 是一个标准的二叉排序树,后序序列为:5,7,6,9,11,10,8 判断过程为: 1.序列5 7 6 9 11 10 8,根结点为8,他的左子树比他小,右子树比他大,从左往右遍历序列找到第一个比8大的数,依此为分界分为左右子树 5 7 6 是左子树, 9 11 10 是右子树,判断一下9 11 10中是否有比8小的数字,如果有则返回false证明不是二叉搜索树。 2.接下来递归判断左子树、右子树是不是二叉搜索树,当都成立时才为真。递归终止条件是左子树为空则返回真,右子树为空返回真,否则返回递归的相与返回值。 原书代码: #include <stdio.h> #include <stdlib.h> #include <vector> using namespace std; bool VerifySquenceOfBST(int sequence[], int length) { if (!sequence || length <= 0) return false; //遍历到左右子树分界点 int *root = sequence + length - 1; int *right = sequence; while (*right < *root) ++right; for (int *p = right; p < root; ++p) { if (*p < *root) return false; } //判断左子树 bool bLeft = true; if (right > sequence) //左子树不为空 bLeft = VerifySquenceOfBST(sequence, right - sequence); //判断右子树 bool bRight = true; if (right < root) //右子树不为空 bRight = VerifySquenceOfBST(right, root - right); return bLeft && bRight; } 牛客网代码,因为原书代码我用了指针,这里我就直接改成迭代器了,很方便: bool VerifySquenceOfBST(vector<int> sequence) { if (sequence.empty()) return false; //遍历到左右子树分界点 auto root = sequence.cend()- 1; auto right = sequence.cbegin(); while (*right < *root) ++right; for (auto p = right; p < root; ++p) { if (*p < *root) return false; } //判断左子树 bool bLeft = true; if (right > sequence.cbegin()) //左子树不为空 { vector<int> leftSeq(sequence.cbegin(), right); bLeft = VerifySquenceOfBST(leftSeq); } //判断右子树 bool bRight = true; if (right < root) //右子树不为空 { vector<int> rightSeq(right, root); bRight = VerifySquenceOfBST(rightSeq); } return bLeft && bRight; } 测试程序: int main() { int a[] = { 7,4,6,5 }; if (VerifySquenceOfBST(a, 7)) printf("true"); else printf("false"); printf("\n"); vector<int>b = { 5,7,6,9,11,10,8}; if (VerifySquenceOfBST(b)) printf("true"); else printf("false"); printf("\n"); getchar(); return 0; } 效果: 总结: 主要是找规律,注意递归结束条件。举一反三,前序序列同样可以做
转载请注明原文地址: https://www.6miu.com/read-84729.html

最新回复(0)