试写一个判别给定二叉树是否为二叉排序树的算法。以前序遍历序列和中序遍历序列给出该二叉树的结点,并创建该二叉树。然后再进行判断。请注意,树中结点关键字可能相同。
【样例输入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; }