【东华大学oj】判断给定的二叉树是否是二叉排序树

判断给定的二叉树是否是二叉排序树

作者: 冯向阳

时间限制: 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Juneeeeeeeeeeeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值