4-06. 搜索树判断
对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式说明:
输入的第一行包含一个正整数N(<=1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。
输出格式说明:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出“YES”,否侧输出“NO”。如果判断结果是“YES”,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。
样例输入与输出:
序号 | 输入 | 输出 |
1 |
7 8 6 5 7 10 8 11 |
YES 5 7 6 8 11 10 8 |
2 |
7 8 10 11 8 6 7 5 |
YES 11 8 10 7 5 6 8 |
3 |
7 8 6 8 5 10 9 11 |
NO |
4 |
16 100 70 60 62 68 65 69 200 150 140 160 155 300 400 500 450 |
YES 65 69 68 62 60 70 140 155 160 150 450 500 400 300 200 100 |
5 |
17 85 92 100 120 110 105 88 90 50 20 30 40 35 36 32 28 15 |
YES 105 110 120 100 90 88 92 36 32 35 40 28 30 15 20 50 85 |
6 |
7 8 6 7 5 10 11 9 |
NO |
7 |
1 -1 |
YES -1 |
-------------------------------------
简单的搜索树中常用函数, 值得注意的是swap 交换的是 左右子树的指针 才能够实现递归的 交换 整个树的左右指针,
而非仅仅交换左右子树上面的数值。 为了方便输出 后续遍历数值的时候在 输出最后 数字后面省略空格符,所以使用 队列 对后续遍历的数值进行存储。
----------------src----------------------
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <queue> using namespace std ; typedef struct BstNode { int data ; struct BstNode *right , *left ; }BstNode ; queue <int> q1 ; queue <int> q2 ; void swap ( BstNode *& T ) { BstNode * tmp = NULL ; if ( !T ) return ; swap( T->left ) ; swap (T->right ) ; tmp = T->left ; //printf("swap : %d %d\n", tmp->data , T->right->data) ; T->left = T->right; T->right = tmp ; } void insert ( BstNode * &T , int data ) { if ( !T ) { T = ( BstNode*)malloc(sizeof(BstNode)) ; T->data = data ; T->left = T->right = NULL ; return ; } else { if ( data >= T->data ) insert( T->right , data ) ; else insert(T->left , data ) ; } } void PreTraverse( BstNode * T ) { if ( !T ) return ; // printf("%d\n", T->data) ; q1.push(T->data) ; PreTraverse ( T->left ) ; PreTraverse ( T->right ) ; } void BacTraverse( BstNode *T ) { if ( !T) return ; BacTraverse( T->left ) ; BacTraverse( T->right ) ; q2.push(T->data) ; } int main ( void ) { BstNode * root = NULL ; int N ,x ,i; int list[1002] ; bool flag = true ; scanf("%d", &N) ; for ( i = 0 ; i < N ; i++ ) { scanf("%d", &(list[i])) ; insert( root, list[i] ) ; } PreTraverse ( root ) ; for ( i = 0 ; i < N ; i++ ) { x = q1.front() ; if ( list[i] != x ) { flag = false ; } q1.pop() ; } if ( !flag ) { swap(root) ; PreTraverse(root) ; flag = true ; for ( i = 0 ; i < N ; i++ ) { x = q1.front() ; if ( x != list[i] ) { flag = false ; break ; } q1.pop () ; } } if ( !flag ) { printf("NO") ; } else { printf("YES\n") ; BacTraverse(root) ; for ( i = 0 ; i < N ; i++ ) { x = q2.front() ; q2.pop() ; printf("%d",x) ; if ( i != N-1 ) printf(" ") ; } } return 0 ; }