需求:
输入一个整数数组,判断该数组是不是某个二叉树的后序遍历的结果,如果是,返回1,否则返回0。
线索:
在后序遍历序列中,最后一个数字是当前二叉树的根节点,所以序列中的数字可以分为三部分,根,左子树,右子树,左子树的值都小于根节点,右子树的值都大于根节点,所以可以根据这个信息找到序列中左子树的长度,之后判断当前二叉树的右子树是否满足条件。如果满足条件,则开始分治,进一步判断左子树和右子树的是否满足条件。
实现:
int verifySequenceOfPostOrder(int data[], int len){
//判断元素是否符合条件
if (data == NULL || len <= 0){
return 0;
}
int root = data[len - 1];
//根据根节点找到当前二叉树的左子树
int i = 0;
for (; i < len - 1; i++){
if (data[i]>root){
break;
}
}
//判断当前二叉树中的右子树是否符合条件
int j = i;
for (; j < len - 1; j++){
if (data[j] < root){
return 0;
}
}
//左二分进一步判断左子树是否满足条件
int leftFlag = 1;
if (i>0){
leftFlag = verifySequenceOfPostOrder(data, i);
}
//右二分进一步判断右子树是否满足条件
int rightFlag = 1;
if (i < len - 1){
rightFlag = verifySequenceOfPostOrder(data + i, len - i - 1);
}
return leftFlag&&rightFlag;
}
调试:
//定义二叉树的节点
typedef struct node{
int data;
struct node *left;
struct node*right;
}BTNode;
//创建二叉搜索树
BTNode* creatBinSortTree(int data[],int len){
BTNode *p = NULL, *pa = NULL, *c = NULL,*root=NULL;
for (int i = 0; i < len; i++){
//为新节点分配单元
p = (BTNode*)malloc(sizeof(BTNode));
//初始化新节点
p->data = data[i];
p->left = p->right = NULL;
if (!root){
root = p;
}
else{
c = root;
while (c){
pa = c;
if (c->data < p->data){
c = c->right;
}
else{
c = c->left;
}
}
if (pa->data < p->data){
pa->right = p;
}
else{
pa->left = p;
}
}
}
return root;
}
//后序遍历二叉树
int PostOrder[8];
int count = 0;
void postOrder(BTNode *root){
if (root){
postOrder(root->left);
postOrder(root->right);
PostOrder[count++] = root->data;//将后序遍历二叉树的序列存到数组中
printf("%d ",root->data);
}
}
//主函数
int main(void){
int data[8] = { 3, 2, 5, 8, 4, 7, 6, 9 };
BTNode *root = creatBinSortTree(data, 8);
printf("后续遍历序列:\n");
postOrder(root);
printf("\n");
printf("%d ", verifySequenceOfPostOrder(PostOrder,count));
printf("\n");
printf("%d ", verifySequenceOfPostOrder(data, 8));
printf("\n");
system("pause");
return 0;
}
调试结果: