判断给定的二叉树是否是二叉排序树
作者: 冯向阳
时间限制: 1s
章节: 课程设计
问题描述
在二叉树的二叉链表存储形式建立的基础上,使用递归的程序设计方法,设计并完成判断一棵给定的二叉树是否是二叉排序树的算法。
初始条件:二叉树T。
操作结果:若T是二叉排序树,则返回true,否则返回false。
提示:
(1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)它的左、右子树也分别为二叉排序树。
(4)递归遍历,左孩子的key比根节点的key小,右孩子的key比根节点的key大,一旦有不满足条件的就判定不是。
参考函数原型:
//判断是否是二叉排序树
template<class ElemType>
bool IsBST(BinaryTreeNode<ElemType> *root); //root为指向根结点的指针
方法2:
提示:
(1)首先对二叉树T进行一次中序遍历,遍历结果存放在顺序表A中
(2)针对顺序表A进行一趟冒泡排序。若交换标志不改变,则说明是一棵二叉排序树。
参考函数原型:
(1)主函数:针对顺序表A进行一趟冒泡排序,判断是否是二叉排序树
template<class ElemType>
bool IsBST(vector<ElemType> &A); //A为存放中序遍历结果的顺序表
(2)辅助函数1
//重载二叉树的中序遍历(用户函数)
template<class ElemType>
bool InOrderTraverse(BinaryTree<ElemType> &T, vector<ElemType> &A);
(3)辅助函数2
//重载二叉树的中序遍历(成员函数)
bool InOrderTraverse( BinaryTreeNode<ElemType> *root, vector<ElemType> &A, bool (*visit1)(BinaryTreeNode<ElemType> *root, vector<ElemType> &A) ) const;
(4)辅助函数3
//重写遍历的visit函数,将遍历结果依次存放在顺序表A中(为避免连锁改动,将函数名由visit改为visit1)
template<class ElemType>
bool visit1(BinaryTreeNode<ElemType> * root, vector<ElemType> &A);
输入说明
第一行:表示无孩子或指针为空的特殊分隔符
第二行:二叉树的层次次序序列(结点元素之间以空格分隔)(参见二叉树ADT的建立 20题)
输出说明
第一行:二叉树的中序遍历结果
第二行:true(是二叉排序树)/false(不是二叉排序树)
#include <iostream>
#include <stack>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
template<class ElemType>
struct BinaryTreeNode
{
ElemType data;
BinaryTreeNode<ElemType>* LChild;
BinaryTreeNode<ElemType>* RChild;
BinaryTreeNode(ElemType item = ElemType(), BinaryTreeNode<ElemType>* L = nullptr, BinaryTreeNode<ElemType>* R = nullptr)
: data(item), LChild(L), RChild(R) {}
};
template<class ElemType>
class BinaryTree
{
private:
BinaryTreeNode<ElemType>* root;
void destroy(BinaryTreeNode<ElemType>*& node)
{
if (node != nullptr)
{
destroy(node->LChild);
destroy(node->RChild);
delete node;
node = nullptr;
}
}
void preorder(BinaryTreeNode<ElemType>* node, vector<ElemType>& result)
{
if (node != nullptr)
{
result.push_back(node->data);
preorder(node->LChild, result);
preorder(node->RChild, result);
}
}
void inorder(BinaryTreeNode<ElemType>* node, vector<ElemType>& result)
{
if (node != nullptr)
{
inorder(node->LChild, result);
result.push_back(node->data);
inorder(node->RChild, result);
}
}
void postorder(BinaryTreeNode<ElemType>* node, vector<ElemType>& result)
{
if (node != nullptr)
{
postorder(node->LChild, result);
postorder(node->RChild, result);
result.push_back(node->data);
}
}
public:
BinaryTree() : root(nullptr) {}
~BinaryTree()
{
destroy(root);
}
void createFromPreorder(vector<ElemType> elements, ElemType empty)
{
auto it = elements.begin();
root = create(it, elements.end(), empty);
}
//层次遍历创建二叉树
void createFromLayer(vector<ElemType> elements, ElemType empty)
{
if (elements.empty())
{
root = nullptr;
return;
}
root = new BinaryTreeNode<ElemType>(elements[0]);
vector<BinaryTreeNode<ElemType>*> nodes;
nodes.push_back(root);
size_t i = 1;
while (i < elements.size())
{
BinaryTreeNode<ElemType>* node = nodes.front();
nodes.erase(nodes.begin());
if (elements[i] != empty)
{
node->LChild = new BinaryTreeNode<ElemType>(elements[i]);
nodes.push_back(node->LChild);
}
++i;
if (i < elements.size() && elements[i] != empty)
{
node->RChild = new BinaryTreeNode<ElemType>(elements[i]);
nodes.push_back(node->RChild);
}
++i;
}
}
BinaryTreeNode<ElemType>* create(typename vector<ElemType>::iterator& it, typename vector<ElemType>::iterator end, ElemType empty)
{
if (it == end || *it == empty)
{
return nullptr;
}
BinaryTreeNode<ElemType>* node = new BinaryTreeNode<ElemType>(*it);
++it;
node->LChild = create(it, end, empty);
++it;
node->RChild = create(it, end, empty);
return node;
}
// 非递归后序遍历算法
void PostOrderTraversal()
{
stack<BinaryTreeNode<ElemType>*> S;
BinaryTreeNode<ElemType>* p = root;
BinaryTreeNode<ElemType>* lastVisited = nullptr;
vector<ElemType> result;
while (p != nullptr || !S.empty())
{
if (p != nullptr)
{
S.push(p);
p = p->LChild;
}
else
{
BinaryTreeNode<ElemType>* topNode = S.top();
if (topNode->RChild != nullptr && topNode->RChild != lastVisited)
{
p = topNode->RChild;
}
else
{
S.pop();
result.push_back(topNode->data);
lastVisited = topNode;
}
}
}
// 输出结果
for (size_t i = 0; i < result.size(); ++i)
{
cout << result[i];
if (i != result.size() - 1)
cout << ",";
}
}
//中序遍历算法
void InOrderTraversal()
{
stack<BinaryTreeNode<ElemType>*> S;
BinaryTreeNode<ElemType>* p = root;
vector<ElemType> result;
while (p != nullptr || !S.empty())
{
if (p != nullptr)
{
S.push(p);
p = p->LChild;
}
else
{
p = S.top();
S.pop();
result.push_back(p->data);
p = p->RChild;
}
}
// 输出结果
for (size_t i = 0; i < result.size(); ++i)
{
cout << result[i];
if (i != result.size() - 1)
cout << ",";
}
}
//判断是否为BST
bool isBST()
{
stack<BinaryTreeNode<ElemType>*> S;
BinaryTreeNode<ElemType>* p = root;
ElemType lastData = ElemType();
while (p != nullptr || !S.empty())
{
if (p != nullptr)
{
S.push(p);
p = p->LChild;
}
else
{
p = S.top();
S.pop();
if (p->data < lastData)
return false;
lastData = p->data;
p = p->RChild;
}
}
return true;
}
};
int main()
{
string nullSymbol;
string preorderInput;
getline(cin, nullSymbol);
getline(cin, preorderInput);
stringstream ss(preorderInput);
string item;
vector<string> elements;
while (ss >> item)
{
elements.push_back(item);
}
BinaryTree<string> tree;
tree.createFromLayer(elements, nullSymbol);
tree.InOrderTraversal();
cout << endl;
tree.isBST() ? cout << "true" : cout << "false";
cout << endl;
return 0;
}