左神算法基础class4—题目7-1判断一棵树是否是搜索二叉树
1.题目:判断一棵树是否是搜索二叉树
2.分析
(1)搜索二叉树
搜索二叉树指任意节点为头的子树,左子树小于头节点,右子树大于头节点。
对于节点3,左子树2小于3,右子树4大于3;
对于节点5,左子树3小于5,右子树8大于5;
对于节点6,右子树7大于6;
对于节点10,左子树9小于10;
对于节点8,左子树6小于8,右子树10大于8;
(2)解题思路
使用中序遍历,中序遍历的输出顺序正好是左中右,而搜索二叉树正好是左小于中,中小于右,那么整个中序遍历输出为升序排列时这棵树为搜索二叉树。
3.核心代码
(1)树的建立
使用二叉链表作为树的存储方式,设计一个数据域、两个指针域(指向左右孩子)。
class Tree
{
public:
int val;
Tree *left;
Tree *right;
//构造函数
Tree(int x){
this->val = x;
this->left = NULL;
this->right = NULL;
}
};
主函数中:
Tree *head = new Tree(5);
head->left = new Tree(3);
head->left->left = new Tree(2);
head->left->right = new Tree(4);
head->right = new Tree(8);
head->right->left = new Tree(6);
head->right->right = new Tree(10);
head->right->left->right= new Tree(7);
(2)中序遍历的非递归
在栈不空或者当前节点不为空的情况下进行循环,当前节点不为空时,入栈并把当前节点指向其左子树;当前节点为空时,出栈,当前节点指向出栈数的右子树。
tips:为什么使用栈来存储?见先序的非递归部分
void inOrderUnRecur(Tree* head)
{
stack<Tree*> t;
while(!t.empty() || head != NULL)
{
//当前节点不为空,入栈并把当前节点指向其左子树
if(head != NULL)
{
t.push(head);
head = head->left;
}
//当前节点为空时,出栈,当前节点指向出栈数的右子树
else
{
head = t.top();
cout<<t.top()->data<<" ";
t.pop();
head = head->right;
}
}
}
(3)更改中序遍历
把中序遍历中打印输出的时机替换为与节点的升序比较,中序遍历使用栈来存储输出顺序,只需要比较当前栈需要弹出的数是否大于上个弹出的数(升序)即可。
bool isBST(Tree *head)
{
stack<Tree *> t;
int pre = INT_MIN;//使用pre存储前一个弹出的数,INT_MIN是系统int型最小的数,因为第一次比较必须小于当前节点
while(!t.empty() || head != NULL)
{
if(head != NULL)
{
t.push(head);
head = head->left;
}
else
{
head = t.top();
//比较:如果上个弹出的数大,不是搜索二叉树
if(t.top()->val < pre)
return false;
pre = t.top()->val;//否则更新pre为现在弹出的数
t.pop();
head = head->right;
}
}
return true;//所有比较完成,前面并没有返回,运行到这里时返回true是搜索树
}
4.完整代码
#include<iostream>
#include<stack>
using namespace std;
class Tree
{
public:
int val;
Tree *left;
Tree *right;
Tree(int x){
this->val = x;
this->left = NULL;
this->right = NULL;
}
};
bool isBST(Tree *head)
{
stack<Tree *> t;
int pre = INT_MIN;//使用pre存储前一个弹出的数,INT_MIN是系统int型最小的数
while(!t.empty() || head != NULL)
{
if(head != NULL)
{
t.push(head);
head = head->left;
}
else
{
head = t.top();
//比较:如果上个弹出的数大,不是搜索二叉树
if(t.top()->val < pre)
return false;
pre = t.top()->val;//否则更新pre为现在弹出的数
t.pop();
head = head->right;
}
}
return true;
}
int main()
{
Tree *head = new Tree(5);
head->left = new Tree(3);
head->left->left = new Tree(2);
head->left->right = new Tree(4);
head->right = new Tree(8);
head->right->left = new Tree(6);
head->right->right = new Tree(10);
head->right->left->right= new Tree(7);
cout<<isBST(head);
system("pause");
return 0;
}