0
点赞
收藏
分享

微信扫一扫

数据结构上机——二叉排序树的优化版本


书接上回
上篇博客
采用了数组记录
的确不太妥当
并且在层数较多时不适用
这里采用了新的一种链表思路
参考
​​​这篇文章​​

//判断二叉排序树的程序代码
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
//二叉链表的结构类型定义
const int maxsize=1024;
typedef int keytype;
typedef struct node
{
keytype key;
struct node *lchild,*rchild;
}bitree;

bitree*creattree();
void preorder(bitree*);
int inorder(bitree*);

int main()
{
bitree*pb;
pb=creattree();
preorder(pb);
printf("\n");
if(inorder(pb)==1)printf("是二叉排序树!\n");
else printf("不是二叉排序树!\n");
}

//二叉树的建立
bitree*creattree()
{
keytype x;
bitree*Q[maxsize];
int front,rear;
bitree*root,*s;
root=NULL;
front=1;rear=0;
printf("按层次输入二叉排序树的整型结点数据,0表示虚结点,-1表示结束:\n");
scanf("%d",&x);//输入0表示虚结点,-1表示结束
while(x!=-1)
{
s=NULL;
if(x!=0)
{
s=(bitree*)malloc(sizeof(bitree));
s->key=x;
s->lchild=NULL;
s->rchild=NULL;
}
rear++;
Q[rear]=s;
if(rear==1)root=s;
else
{
if(s&&Q[front])
if(rear%2==0)Q[front]->lchild=s;
else Q[front]->rchild=s;
if(rear%2==1)front++;
}
scanf("%d",&x);
}
return root;
}

//二叉树的输出
void preorder(bitree*p)
{
if(p!=NULL)
{
printf("%d",p->key);
if(p->lchild!=NULL||p->rchild!=NULL)
{
printf("(");
preorder(p->lchild);
if(p->rchild!=NULL) printf(",");
preorder(p->rchild);
printf(")");
}
}
}
/*判断左子树的结点值是否都小于val*/
int isSubTreeLessThan(bitree*p, int val)
{
if (!p) return 1;
return (p->key < val &&
isSubTreeLessThan(p->lchild, val) &&
isSubTreeLessThan(p->rchild, val));
}
/*判断右子树的结点值是否都大于val*/
int isSubTreeGreaterThan(bitree*p, int val)
{
if (!p) return 1;
return (p->key > val &&
isSubTreeGreaterThan(p->lchild, val) &&
isSubTreeGreaterThan(p->rchild, val));
}
/*判定二叉树是否是二叉搜索树*/
int inorder(bitree*p)
{
if (!p) return 1;
return isSubTreeLessThan(p->lchild, p->key) &&
isSubTreeGreaterThan(p->rchild, p->key) &&
inorder(p->lchild) &&
inorder(p->rchild);
}

乍一看以为一个return带着四个条件的写法过于融合
经过一思考发现这是最为简洁巧妙的写法
算法思路是这样:
在判断一个节点的同时,
不断递归考察下一代的情况,
考察顺序:先判断左侧所有节点是否小于该节点,再判断右侧所有节点是否大于该节点
这种递归中又嵌套递归的方法不禁令人拍案叫绝!
虽然递归算法最大的弊病是时间的冗余,但思路的清晰对于初学者来说更为重要。
尤其是该方法直接判断空结点返回1,从而避免了对虚节点的讨论,妙不可言。


举报

相关推荐

0 条评论