试写一个判别给定二叉树是否为二叉排序树的算法。以前序遍历序列和中序遍历序列给出该二叉树的结点,并创建该二叉树。然后再进行判断。请注意,树中结点关键字可能相同。

试写一个判别给定二叉树是否为二叉排序树的算法。以前序遍历序列和中序遍历序列给出该二叉树的结点,并创建该二叉树。然后再进行判断。请注意,树中结点关键字可能相同。

【样例输入1】

6 4 5 8 6 9 0

4 5 6 6 8 9 0
【样例输出1】

true

难点:创建树时下标确定,中序递归遍历顺序

思想:递归的特点,中序遍历访问顺序

#include<iostream>
#define MAX 50
using namespace std;
//定义树节点
typedef struct TreeNode {
	int data;
	TreeNode* ltree=NULL, * rtree=NULL;
}TreeNode;
typedef TreeNode* Tree;
//进行前序和中序数组输入,这里是从1号下标开始,0号记录元素个数
void Cin(int pre[], int last[]) {
	int i = 0, j = 0;
	do {
		i++;
		cin >> pre[i];
	} while (pre[i] != 0);
	pre[0] = i - 1;
	do {
		j++;
		cin >> last[j];
	} while (last[j] != 0);
	last[0] = j - 1;

}
//树的创建,(根节点,前序数组,中序数组,前序数组左指针、指向该树的根节点,右指针、指向该树最后一个节点,中序做指针、指向该树最左下节点,右指针、指向最右下节点)
void Crtree(Tree &root, int pre[], int last[], int pl, int pr, int ll, int lr) {
	if (pl > pr || ll > lr) {
		root = NULL;
		return;
	}//这里若pl==pr时代表还有一个节点
	int num = 0;
	for (num = ll; num < lr; num++) {
		if (pre[pl] == last[num]) {
			break;
		}
	}//找中序中pre[ll]即这个树根节点位置
	root = (Tree)malloc(sizeof(TreeNode));
	root->data = pre[pl];
	Crtree(root->ltree, pre, last, pl + 1, pl + num - ll, ll, num - 1);//前序中pl处是是该树根节点,对应pl+1是ltree根节点,num-ll是该树左树节点数,pl+num-11就是ltree的最右下节点对应坐标,中序中:ll是ltree根节点,num-1ltree的最右下节点对应坐标
	Crtree(root->rtree, pre, last, pl + 1 + num-ll, pr, num + 1, lr);//前序中pl+num-11就是ltree的最右下节点对应坐标,那么再加一就是rtree根节点处,pr就是rtree最后一个节点,
}
//用中序遍历的思想判断每个节点是否比其中序前驱节点大
bool Judge(Tree root,int &pre) {//注意这里要用引用或指针
	if (root == NULL) {
		return true;
	}
	bool regard;
    regard = Judge(root->ltree, pre);
	if (pre > root->data||regard==false) {
		return false;
	}
	pre = root->data;
	return Judge(root->rtree, pre);
}
int main() {
	int pre[MAX], last[MAX];
	Cin(pre, last);
	Tree root;
	Crtree(root, pre, last, 1, pre[0], 1, last[0]);
	int premin = -999;
	if (Judge(root,premin)) {
		cout << "true";
	}
	else {
		cout << "false";
	}
	return 0;
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值