思考:
类比链式存储方式,如果是链式存储,则直接中序遍历二叉树,然后看中序值是否是递增的,如果递增则是BST,否则不是。
顺序存储要解决的问题:
- 首先遍历条件是结点不为空,在顺序存储中实现方式就是判断数组下标是否超出数组长度,并且数组元素值不为-1,因为-1代表空节点
- 遍历中访问的元素,链式存储中递归遍历可以直接访问值,但是顺序存储就需要将值保存下来,可以定义一个一维数组,用来保存中序遍历的值
- 遍历数组,如果数组是递增,则是,如果不是,则不符合条件
代码演示:
typedef struct
{
int SqBiTNode[MAX_SIZE]; //保存⼆叉树结点值的数组
int ElemNum; //实际占⽤的数组元素个数
} SqBiTree;
int a[MAX_SIZE]= {0}; //定义一个全局变量数组保存中序遍历的值,初始为0
int k = 0; //k是全局变量数组对应的下标
void Inorder1(SqBiTree *q,int i)
{
if(i < q->ElemNum && q->SqBiTNode[i] != -1)//相当于链表存储的p!=NULL
{
Inorder1(q,2*i+1);
a[k++] = q->SqBiTNode[i];
Inorder1(q,2*i+2);
}
}
bool judgeBST(SqBiTree *T,int i)
{
Inorder1(T,0);
for(int i=1;i<k;i++)//k最后指向下标是数组结尾元素的后一个位置,也就对应了数组元素总个数
{
if(a[i-1]>a[i])
{
return false;
}
}
return true;
}
- 时间复杂度O(n),空间复杂度O(n)
拓展:
使用链式存储实现
代码演示:
typedef struct BTNode{
int data;
struct *lchild,*rchild;
}BTNode,*BTree;
int temp = INT_MIN;//记录当前遍历到的最小值,初始设为最小值
bool isBST = true;//记录是否是完全二叉树
void inOrdr(BTNode *T)
{
if(T == NULL)
{
return;//是完全二叉树
}
inOrdr(T->lchild);//递归遍历左子树
if(T->data >= temp)
{
temp = T->data;
}else{
isBST = false;//说明中序遍历的前一个节点值比后一个值大,不是二叉排序树
}
inOrdr(T->rchild);//递归遍历右子树
}
在main()函数中调用inOredr(root),执行结束,如果isBST=true,则是二叉排序树,否则不是