一:题目
对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。
现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。
输入格式:
输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。
输出格式:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES,否侧输出NO。如果判断结果是YES,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。
输入样例1:
7
8 6 5 7 10 8 11
输出样例1:
YES
5 7 6 8 11 10 8
输入样例2:
7
8 6 8 5 10 9 11
输出样例2:
NO
二:思路
1:关于键值重复问题可以重复 安排到右子树即可 保证中序当中整体的递增序列不变 2:解决二叉搜索树 根据输入的序列进行建树 输出遍历顺序3:(如果上诉否 那么就用这个)解决镜像二叉搜索树利用层序遍历(将输出的顺序 改为先输出右结点 再输出左结点) 得到层序顺序后根据 层序顺序建树 3(2.0):写完前面的码后感觉 再写一个建树有点麻烦 重新捋捋 镜像 就是将前序函数中的递归函数先输出左改成右边 同时后序也是4:如果都否的话 输出 NO
三:上码
/*1:关于键值重复问题可以重复 安排到右子树即可 保证中序当中整体的递增序列不变 2:解决二叉搜索树 根据输入的序列进行建树 输出遍历顺序3:(如果上诉否 那么就用这个)解决镜像二叉搜索树利用层序遍历(将输出的顺序 改为先输出右结点 再输出左结点) 得到层序顺序后根据 层序顺序建树 3(2.0):写完前面的码后感觉 再写一个建树有点麻烦 重新捋捋 镜像 就是将前序先输出左改成右边 同时后序也是 4:如果都否的话 输出 NO
*/
#include<bits/stdc++.h>
using namespace std;typedef struct TNode*Ptrtree;
typedef struct TNode{int Data;Ptrtree left;Ptrtree right;
}tnode; int N;
vector<int>v1,v2,v3,v4; //建立二叉搜索树
Ptrtree insert(Ptrtree root,int x){//插入完第一个后 根节点也就固定了 if(root == NULL){//将插入的操作视为 查找的时的操作,插入的地点视为 查找失败的地点 在查找失败的地点 插入一个结点root = (Ptrtree)malloc(sizeof(struct TNode));root->left = NULL;root->right = NULL;root->Data = x;return root;}if(root->Data > x){root->left = insert(root->left,x);}else if(root->Data <= x){root->right = insert(root->right,x);}else{return NULL;}return root;
}Ptrtree creatTree(int A[],Ptrtree root){root = NULL;int i;for(i = 0; i < N; i++){root = insert(root,A[i]);}return root;
}
//二叉搜索树的前序遍历
void Preorder1( Ptrtree root )
{if( root != NULL){int temp = root->Data;v1.push_back(temp); Preorder1(root->left);Preorder1(root->right);}
}
//二叉搜索树的后序遍历
void Postorde1(Ptrtree root)
{if(root != NULL){Postorde1(root->left);Postorde1(root->right);int temp = root->Data;v2.push_back(temp); }
}//二叉镜像树的前序遍历
void Preorder2( Ptrtree root )
{if( root != NULL){int temp = root->Data;v3.push_back(temp); Preorder2(root->right);Preorder2(root->left);}
}//二叉镜像树的后序遍历
void Postorde2(Ptrtree root)
{if(root != NULL){Postorde2(root->right);Postorde2(root->left);int temp = root->Data;v4.push_back(temp); }
}//比较两个容器当中的数据是否相等
int judgment( int a[],vector<int>&v)
{int flag = 0;for(int i = 0; i < N; i++){if(a[i] != v[i]){flag = 1;break; }}if( flag == 0)return 1;elsereturn 0;
}int main(){int a[1000];cin >> N;for(int i = 0; i < N; i++){cin >> a[i]; } Ptrtree root;root = creatTree(a,root);Preorder1(root);int flag1 = judgment(a,v1); //判断二叉搜索树的前序是否正确 //如果是二叉搜索树的前序序列 正确 if( flag1 == 1 ){cout << "YES" << endl;Postorde1(root);for( int i = 0; i < v2.size(); i++ ){if( i != N-1) cout << v2[i] << ' ';elsecout << v2[i];}}else { //比较是否是镜像的二叉树Preorder2(root);int flag2 = judgment(a,v3);if( flag2 == 1 ){cout << "YES" << endl;Postorde(root);for( int i = 0; i < N; i++ ){if( i != N-1) cout << v4[i] << ' ';elsecout << v4[i];}}else{cout << "NO"; } }}
哈哈哈 哈哈哈哈哈哈哈哈 提前下班了 哈哈哈哈 再见明天见 老样子 加油陌生的的你!