如何判断一棵二叉树是二叉查找树

zengkun100 2006-12-23 07:43:14
二叉查找树的定义我就不说了吧!

我开始想的方法是:递归地判断某节点的左右子树是不是二叉查找树,然后再判断该节点是不是比它的左节点大,比右节点小。但是这是个错误的方法。
我后来的想法是:
对一个节点,找到它的左子树的最大节点MAX和右子树的最小节点MIN,然后判断该节点是否比MAX大比MIN小。然后在递归地判断它的左子树和右子树。

不知道有没有什么更好的办法呢?
...全文
910 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
zengkun100 2007-01-12
  • 打赏
  • 举报
回复
过了这么多天,发现Kusk(Kusk)的算法是对的。可惜没有给分!的确只需要中序遍历一次就好了。
zengkun100 2007-01-01
  • 打赏
  • 举报
回复
比如说:有一个结点的值是10,
它的左孩子结点的值为5,右孩子结点的值为20;
而对值为5的那个孩子结点,它只有一个右孩子,值为15,
这样一颗树不是二叉排序树
fosjos 2006-12-29
  • 打赏
  • 举报
回复
呵呵,楼上二位又范了同样的错

二杈查找树是左子树所有节点值都小于子树的根,而右子树所有节点值都大于子树的根
所以我觉得栈里保存的应该是子树的min和max
HappyTree 2006-12-29
  • 打赏
  • 举报
回复
Kusk(Kusk)的办法,我觉得挺好的,思路也比较清晰
Kusk 2006-12-29
  • 打赏
  • 举报
回复
楼上的,错在何处呢?可否具体举例?
Kusk 2006-12-29
  • 打赏
  • 举报
回复
编历-->遍历
sorry打错。
Kusk 2006-12-29
  • 打赏
  • 举报
回复
中序编历一遍,每次比较当前结点值与前一个结点值的大小关系是否满足,就行了吧?
zengkun100 2006-12-28
  • 打赏
  • 举报
回复
是啊!
初一想还觉得判断一下该节点与左右节点的关系之后继续递归地判断就行了,其实要找出左子树的最大节点和右子树的最小节点。
fosjos 2006-12-28
  • 打赏
  • 举报
回复
我上面贴的递归判断每个子树的min和max节点应该没问题
genius_hb 2006-12-28
  • 打赏
  • 举报
回复
哈哈,当年我去某大公司面试就碰到这题目,虽然很简单但也弄错了.....
楼上几位想过没:

14
13 30
10 45
这是个排序二叉树吗??你们的代码能识别吗?

哎~~~~~~~~~~~~那个后悔啊
zengkun100 2006-12-27
  • 打赏
  • 举报
回复
当然是说时间复杂度了,我的想法的时间复杂度是O(n*n)。也许没有更好的办法了。
v2002750 2006-12-25
  • 打赏
  • 举报
回复
不知道更好是要多好,写成非递归的怎么样?
<class T >bool isAvl(AvlTree<T> tree){
Node<T> *p=GetHead(tree);
stack<Node<T> *> nodestack;
nodestack.push(p);

while(!nodestack.empty()){
Node<T> *p=0;

while((p=nodestack.top())&&p){//向左走到尽头
nodestack.push(p->left);
}

nodestack.pop();//空指针退栈

if(!nodestack.empty()){//访问结点,向右一步
p=nodestack.top();
nodestack.pop();

//judge判断这个节点是不是大于左子节点小于右子节点,需要处理子节点为空的情况
if(!judge(p))
return false;

nodestack.push(p->right);
}
}
return true;
}
fosjos 2006-12-25
  • 打赏
  • 举报
回复
////如果符合条件,返回root为根的子树的min和max两个node
////否则返回NULL
Node* judge(Node* root){
Node* list = new Node*[2];////list[0]记录min ,list[1]记录max
list[0]=list[1]=root;////如果没有child node ,两个node都是本身
if(root->lchild){
Node* childlist = judge(root->lchild);////获得左子树的min和max
if(!childlist || childlist[1]->data > root->data){////判断是否二叉排序树
if(childlist)delete [] childlist;
delete [] list;
return NULL;
}
list[0] = childlist[0];////left child的min就是该子树的min
delete [] childlist;
}
////right child过程与left child相同
if(root->rchild){
Node* childlist = judge(root->rchild);
if(!childlist || childlist[0]->data < root->data){
if(childlist)delete [] childlist;
delete [] list;
return NULL;
}
list[1] = childlist[1];
delete [] childlist;
}
return list;
}
fosjos 2006-12-24
  • 打赏
  • 举报
回复
bool judge(Node *root){
return !root
||(!root->lchild || root->lchild->data <= root->data && judge(root->lchild))
&&(!root->rchild || root->rchild->data >= root->data && judge(root->rchild));
}
或者
bool judge(Node *root){
return !root
||(!root->lchild || root->lchild->data <= root->data)
&&(!root->rchild || root->rchild->data >= root->data)
&& judge(root->lchild)) && judge(root->rchild));
}
zengkun100 2006-12-24
  • 打赏
  • 举报
回复
我都说了不能那样写了,fosjos(无聊的菜鸟程序员)还那样写,那是错的。
v2002750(),我说的是二叉排序树。
没有什么更好的办法吗?
v2002750 2006-12-24
  • 打赏
  • 举报
回复
难道你说的是二叉排序树?
你说的那个方法挺好的,写成非递归的也可以啊。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧