BST(二叉搜索树)
特征:
根节点的值大于其左子树中任意一个节点的值,小于其右节点中任意一节点的值
目的:
是为了提高查找的性能,其查找在平均和最坏的情况下都是logn级别,接近二分查找。
后序遍历
先遍历输出左结点,再遍历输出右结点,最后输出当前结点的数据。
由于BST的特征,最后一个数字是树的根节点 ,数组中前面的数字可以分为两部分:第一部分是 左子树节点 的值,都比根节点的值小;第二部分是 右子树节点 的值,都比根节点的值大。
剑指offer_23
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路:
采用分治法的思想,找到根结点、左子树的序列、右子树的序列,分别判断左右子序列是否为二叉树的后序序列。
算法步骤如下:
- 找到根结点;
- 遍历序列,找到第一个大于等于根结点的元素mid,则mid左侧为左子树、mid右侧为右子树;
- 我们已经知道mid左侧所有元素均小于根结点,那么再依次遍历右侧,看是否所有元素均大于根结点;若出现小于根结点的元素,则直接返回false;若右侧全都大于根结点,则:
- 分别递归判断左/右子序列是否为后序序列;
class TreeNode // 树结点结构
{
public:
TreeNode *right;
TreeNode *left;
int val;
TreeNode(int r) : val(r), left(NULL), right(NULL) {}
};
class BinaryTree // 二叉树结构
{
private:
TreeNode *root; // 根结点
int refvalue; //停止条件
public:
BinaryTree(int ref) : refvalue(ref), root(NULL) {}
TreeNode *Create() // 创建二叉树
{
TreeNode *t, *t1, *t2;
int item;
cin >> item;
if (item == refvalue)
return NULL;
else
{
t = new TreeNode(item);
t1 = Create();
t->left = t1;
t2 = Create();
t->right = t2;
return t;
}
}
vector<int> PostOrdor(TreeNode *t) // 非递归后序遍历
{
vector<int> res; //存储后续遍历结果
if (t == NULL)
return res;
stack<TreeNode *> s; // 存储树的结点
s.push(t);
TreeNode *lastpop = NULL; // 记录上次pop的结点
while (!s.empty())
{
while (s.top()->left != NULL) //如果栈顶结点的左子树不空,则压入栈中
s.push(s.top()->left);
while (!s.empty())
{
if (lastpop == s.top()->right || s.top()->right == NULL)
{
// 如果上次pop的是当前栈顶结点的右子树
// 或是当前栈顶结点的右子树为空
// 记录当前栈顶结点的值,并出栈,修改lastpop
res.push_back(s.top()->val);
lastpop = s.top();
s.pop();
}
else if (s.top()->right != NULL)
{
// 如果当前栈顶结点的右子树不空,则压入栈中
// 然后跳出循环,把这个右子树根结点的左结点压入栈中
s.push(s.top()->right);
break;
}
}
}
return res;
}
bool judge(vector<int> &a, int l, int r)
{
// 后序遍历的最后一个结点时树的根结点
if (l >= r)
return true;
int mid = l;
while (mid < r && a[mid++] < a[r]); // 找到比根节点小的
int back = mid;
while (back < r && a[back++] > a[r]); //找到比根结点大的
if (back < r) // 没有到达根结点
return false;
if (mid == l) // 没有比根结点小的
return judge(a, l, r - 1);
else // 有比根节点小的结点
return (judge(a, l, mid - 1) && judge(a, mid, r - 1));
}
bool VerifySquenceOfBST(vector<int> sequence)
{
if (sequence.size() == 0)
return false;
return judge(sequence, 0, sequence.size() - 1);
}
};
int main()
{
BinaryTree *tree = new BinaryTree(0); //创建停止位为0的树
TreeNode *t = tree->Create(); // 创建树
vector<int> m = tree->PostOrdor(t); // 后序遍历
for (int i = 0; i < m.size(); i++)
cout << m[i] << " ";
cout << endl;
// 判断该后续遍历结果是否时某个二叉搜索树的后续遍历结果
bool results = tree->VerifySquenceOfBST(m);
cout << results << endl;
}