左神算法基础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; 
}
发布了51 篇原创文章 · 获赞 1 · 访问量 1372

猜你喜欢

转载自blog.csdn.net/shi_xiao_xuan/article/details/104038033