HDU 3791 二叉搜索树
判断两序列是否为同一二叉搜索树序列
Input开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。Output如果序列相同则输出YES,否则输出NO
Sample Input
2 567432 543267 576342 0
Sample Output
YES NO
解题思路:
本题要求以第一个字符串建立二叉搜索树,之后每行一个给出n个字符串,如果以该行字符串所建立的二叉搜索树与第一个字符串所建立的树相同输出YES,否则输出NO。可以考虑设计一个inPut函数,记录输入的每个字符串,并使用输入输出控制类istringstream创建一个对象绑定我们记录的字符串并模拟C++风格串流的输入操作将每一个字符加入到一个容器中以便建树时使用(当然直接遍历记录的字符串也可以)。改进一下先序遍历函数将树的先序遍历记录到一个字符串中,之后每个先序遍历字符串与第一个输入的树的先序遍历字符串比较就可以了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef char typeData; 4 struct node{ 5 typeData data; 6 node *leftChild; 7 node *rightChild; 8 node(){ //构造函数 9 leftChild = NULL; 10 rightChild = NULL; 11 } 12 }; 13 vector<typeData> data; //data记录输入字符串的每一个元素 14 string text, pattern; 15 //text用来记录第一个字符串所建的二叉搜索树的前序遍历 16 //pattern记录之后每一行输入所建立的二叉搜索树的前序遍历 17 void inPut(){ 18 string temp1, temp2; //temp记录输入的字符串 19 typeData num; 20 temp2 = ""; 21 data.clear(); //每次建树都要清空容器,清空temp2字符串 22 cin >> temp1; 23 24 for(string::iterator it = temp1.begin(); it != temp1.end(); it++){ 25 if(it != temp1.begin()){ 26 temp2 += ' '; 27 } //将temp1中的每一个元素用空格分隔并记录在temp2中 28 temp2 += *it; 29 } 30 istringstream cin_line(temp2); //istringstream绑定temp2 31 while(cin_line >> num){ 32 data.push_back(num);//记录的值加入容器 33 } 34 } 35 void insertBST(node *&root, typeData x){ //二叉搜索树插入函数 36 //注意函数要进行插入操作,根结点要传引用 37 if(root == NULL){ //找到空位置即使插入位置 38 root = new node(); //新建结点权值为x 39 root->data = x; 40 return; 41 } 42 if(x == root->data){ //要插入结点已存在直接返回 43 return; 44 }else if(root->data > x){ //x比根结点数据域小 需要插在左子树 45 insertBST(root->leftChild, x); //往左子树搜索 46 }else if(root->data < x){ //x比根结点数据域大 需要插在右子树 47 insertBST(root->rightChild, x); //往右子树搜索 48 } 49 } 50 node *createBST(){ //建树 51 node *root = NULL; //新建结点root 52 for(vector<typeData>::iterator it = data.begin(); it != data.end(); it++){ 53 insertBST(root, *it); //将容器中我们处理好的值插入二叉搜索树 54 } 55 return root; //返回根结点 56 } 57 void preorder(node *root, string &str){ 58 //改进先序遍历函数,将先序遍历记录在str中,由于要修改str所以传引用 59 if(root == NULL) //到达空树为递归边界 60 return; 61 str += root->data; //访问根结点记录数据到str 62 preorder(root->leftChild, str); //访问左子树 63 preorder(root->rightChild, str); //访问右子树 64 } 65 int main() 66 { 67 int n; 68 while(cin >> n){ //本题有多组测试数据 69 if(n == 0) //如果输入的n为0跳出循环 70 break; 71 inPut(); //输入字符串 72 node *root = createBST(); //建树 73 text = ""; //清空text 74 preorder(root, text); //text记录首位二叉搜索树 75 while(n--){ //输入n个字符串建树比较 76 inPut(); 77 node *root = createBST(); 78 pattern = ""; 79 preorder(root, pattern); 80 if(text == pattern) 81 cout << "YES" << endl; 82 else 83 cout << "NO" << endl; 84 85 } 86 } 87 return 0; 88 }