首页 > 试题广场 >

二叉搜索树

[编程题]二叉搜索树
  • 热度指数:15163 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
判断两序列是否为同一二叉搜索树序列

输入描述:
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。


输出描述:
如果序列相同则输出YES,否则输出NO
示例1

输入

2
567432
543267
576342
0

输出

YES
NO
//既然表哥们都用前序和后序来判断BST是否相等
//那我换种:用层次遍历序列来判断
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
using namespace std;
vector<int>a,b;
struct node
{
    char data;
    node *lchild,*rchild;
};
void layerorder(node *root,vector<int>&v)
{
    queue<node*>q;
    q.push(root);
    while(!q.empty())
    {
        node *now=q.front();
        q.pop();
        v.push_back(now->data);
        if(now->lchild!=NULL)
            q.push(now->lchild);
        if(now->rchild!=NULL)
            q.push(now->rchild);
    }
}
void insert(node *&root,int x)
{
    if(root==NULL)
    {
        root=new node;
        root->data=x;
        root->lchild=root->rchild=NULL;
    }
    else if(x<root->data)
        insert(root->lchild,x);
    else
        insert(root->rchild,x);
}
int main()
{
    int n;
    string temp,str;
    while(cin>>n&&n)
    {
        cin>>temp;
        node *t=NULL;
        a.clear();
        for(int i=0;i<temp.size();i++)
        {
            insert(t,temp[i]);
        }
        layerorder(t,a);
        for(int i=0;i<n;i++)
        {
            cin>>str;
            node *s=NULL;
            b.clear();
            for(int i=0;i<str.size();i++)
                insert(s,str[i]);
            layerorder(s,b);
            if(a==b)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }

    }
    return 0;
}

发表于 2018-03-18 09:16:33 回复(0)
#include <iostream>
#include <string.h>
using namespace std;
struct Node{
    Node *lchild;
    Node *rchild;
    int  num;
}Tree[201];
int doc;
Node *create(){
    Tree[doc].lchild=Tree[doc].rchild=NULL;
    return &Tree[doc++];

char pre1[21],pre2[21],in1[21],in2[21];        //记录原始二叉排序树、目标二叉排序树的前中序序列 
int p1,p2,i1,i2;
void PreOrder(Node *T,int x){                //x=0,1 分别为对原始和目标二叉树前序遍历 
    if(T==NULL) return;
    if(x==0){
        pre1[p1++]=T->num+'0';
    }else{
        pre2[p2++]=T->num+'0';
    }
    PreOrder(T->lchild,x);
    PreOrder(T->rchild,x);
}

void InOrder(Node *T,int x){            //x=0,1 分别为对原始和目标二叉树中序遍历 
    if(T==NULL) return;
    PreOrder(T->lchild,x);
    if(x==0){
        in1[i1++]=T->num+'0';
    }else{
        in2[i2++]=T->num+'0';
    }
    PreOrder(T->rchild,x);
}

Node *Insert(Node *T,int c){
    if(T==NULL){
        T=create();
        T->num=c;
    }
    if(c<T->num) T->lchild=Insert(T->lchild,c);
    if(c>T->num) T->rchild=Insert(T->rchild,c);
    return T;
}
int main(){
    int n;
    while(cin>>n){
        if(n==0) break;
        char origin[21];
        Node *T=NULL;
        doc=0;
        cin>>origin;
        for(int i=0;origin[i]!=0;i++){
            T=Insert(T,origin[i]-'0');            //构造原字符串的二叉树 
        }
        p1=0;p2=0;i1=0;i2=0;
        PreOrder(T,0);
        InOrder(T,0);
        for(int i=0;i<n;i++){
            char des[21];
            Node *t=NULL;
            cin>>des;
            for(int j=0;des[j]!=0;j++){
                t=Insert(t,des[j]-'0');
            }
            PreOrder(t,1);
            InOrder(t,1);
            if(strcmp(pre1,pre2)==0&&strcmp(in1,in2)==0) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
            p2=0;i2=0;
        }
    }
    return 0;
}

发表于 2019-03-01 22:26:24 回复(0)
由二叉树的基本知识可知,中序遍历和另一种遍历可以唯一确定一棵二叉树。所以这里为了比较是否为 常同一二叉树就需要比较中序遍历和先序遍历(后序当然也可以)。规解法是首先将序列构成二叉搜索树,将其先序和中序遍历的字符串拼接起来 (strcat),或用指针拼接。再比较第一个序列与后续序列的拼接字符串(先序遍历和中序遍历拼接的字符串)的异同,输入YES或NO。这里的不好操作的地方在于字符串拼接strcat。以及逐个输入数字(最好当成字符char,会简便很多,方便后面的字符串操作,不用来回转换),构建二叉搜索树的方法就是常用的insert。
另外,由楼上某位大神所说的,完全相同数字没有重复的序列构成的二叉搜索树的中序遍历是一样的(中序遍历都是按数字大小升序排列,所以肯定一样),所以不需要再比较中序遍历的字符串了,所以也不用进行拼接,直接比较先序或者后序遍历的字符串就行了,如下所示,其中注释掉的代码就是比较常规,略繁琐的解法。
#include <stdio.h>
#include <string.h>
struct node{
    node *rchild;
    node *lchild;
    char c;
}tree[120];
int u;
node *create()
{
    tree[u].lchild=tree[u].rchild=NULL;
    return &tree[u++];
}
int size;
//char *str;
void preorder(node *t,char str[])
{
    str[size++]=t->c;
    if(t->lchild)preorder(t->lchild,str);
    if(t->rchild)preorder(t->rchild,str);
}
void inorder(node *t,char str[])
{
    if(t->lchild)inorder(t->lchild,str);
    str[size++]=t->c;
    if(t->rchild)inorder(t->rchild,str);
}
node *insert(node *t,char x)
{
    if(t==NULL){
        t=create();
        t->c=x;
        return t;
    }
    else if(x<t->c)
        t->lchild=insert(t->lchild,x);
     else if(x>t->c)
         t->rchild=insert(t->rchild,x);
    return t;
}
char str1[15];//str2[15]; 
//int size1,size2;
char a[15];//b[15];
int main()
{
    int n;
    while(scanf ("%d",&n)!=EOF&&n!=0)
    {
        u=0;//这个地方很容易忘,如果没写会导致段错误!
        scanf("%s",str1);
        node *t=NULL;
        for(int i=0;str1[i]!=0;++i)
        {
            t=insert(t,str1[i]);
        }
        size=0;
        preorder(t,str1);
        //size=0;
        //inorder(t,str2);
        //strcat(str1,str2);
        while(n--)
        {
            scanf("%s",a);
            node *t1=NULL;
            for(int i=0;a[i]!=0;++i)
            {
                t1=insert(t1,a[i]);
            }
            size=0;
            preorder(t1,a);
            //size=0;
            //inorder(t1,b);
            //strcat(a,b);
            puts(strcmp(str1,a)!=0 ? "NO":"YES");
        }
    }
    return 0;
}
发表于 2018-01-15 22:46:19 回复(1)
#include<bits/stdc++.h>
using namespace std;
//思路为构造二叉排序树,构造完判断两个二叉排序树是否一样
struct TreeNode
{
    int data;
    TreeNode*left;
    TreeNode*right;
    TreeNode(int data):data(data),left(NULL),right(NULL){}
};
TreeNode* Insert(TreeNode*root,int x)
{
    if(root==NULL)
    {
        root=new TreeNode(x);
        return root;
    }
    else if(x<root->data)
        root->left=Insert(root->left,x);
    else if(x>root->data)
        root->right=Insert(root->right,x);
    return root;
}
bool TreeEqual(TreeNode*root1,TreeNode*root2)//判断相等
{ 
    if(root1==NULL&&root2==NULL)
        return true;
    if(root1->data!=root2->data)
        return false;
    return TreeEqual(root1->left,root2->left)&&TreeEqual(root1->right,root2->right);
}
int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        TreeNode*root1=NULL;
        string bsTree;//第一个二叉排序树
        cin>>bsTree;
        for(int i=0;i<bsTree.size();i++)
                root1=Insert(root1,bsTree[i]-'0');//建立二叉排序树
        while(n--)//之后的二叉排序树
        {
            TreeNode*root2=NULL;
            string needCheck;
            cin>>needCheck; //需要检查的序列
            for(int i=0;i<needCheck.size();i++)
                root2=Insert(root2,needCheck[i]-'0');//建立二叉排序树
            if(TreeEqual(root1,root2))
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
    }
    return 0;
}

发表于 2022-03-17 17:12:47 回复(0)
#include<iostream>
#include<string>
using namespace std;

typedef struct Node
{
    int c;
    Node *left,*right;
    Node(int d):c(d),left(NULL),right(NULL){}
}Node;


Node *BuildTree(Node *root,int n)
{
    if(!root)
    {
        root = new Node(n);
    }
    else if(root->c > n)
    {
        root->left = BuildTree(root->left,n); 
    }
    else
    {
        root->right = BuildTree(root->right,n);
    }
    return root;
}

Node *Creat(Node *root,string s)
{
    for(int i = 0;i < s.size();i++)
    {
        root = BuildTree(root,s[i] - '0');
    }
    return root;
}

bool Judge(Node *root1,Node *root2)
{
    if(!root1 && !root2)
    {
        return true;
    }
    else if((!root1 && root2) || (root1 && !root2) || root1->c != root2->c)
    {
        return false;
    }
    else
    {
        return Judge(root1->left,root2->left) && Judge(root1->right,root2->right);
    }
}

int main()
{
    int n;
    while(cin >> n && n)
    {
        string s;
        Node *root1 = NULL;
        cin >> s;
        root1 = Creat(root1,s);
        while(n--)
        {
            Node *root2 = NULL;
            cin >> s;
            root2 = Creat(root2,s);
            if(Judge(root1,root2))
            {
                cout << "YES" << endl;
            }
            else
            {
                cout << "NO" << endl;
            }
        }
    }
    return 0;
}

发表于 2021-02-01 22:12:45 回复(0)
	
/*
*看到讨论区很多吧树全部建立后,和模板树做匹配检测,其实duck不必。
*可以在建立完模板树之后,后面的测试树,只需要建树和匹配同时进行即可,
*一旦发现当下节点不匹配,直接返回false,而无需等树建完。
*/

#include<bits/stdc++.h>

using namespace std;

struct Node
{
    int v;
    struct Node* lchild,* rchild;
};

Node* newNode(int x)    //这个完全可以写个构造函数取代
{
    Node* t = new Node;
    t->v = x;
    t->lchild = t->rchild = nullptr;
    return t;
}

void Insert(Node*& root, int x)    /节点插入
{
    if(root == nullptr)
    {
        root = newNode(x); return ;
    }
    if(root->v == x) return ;
    else if(root->v < x) Insert(root->rchild, x);
    else Insert(root->lchild, x);
}

Node* Create(string s)   //创建模板树
{
    Node* root = nullptr;
    for(char c : s)
        Insert(root, c-'0');
    return root;
}

bool Search(Node* root, Node*& root1, int x)    //建树与测试同步
{
    if(root1 == nullptr)
    {
        root1 = newNode(x); return root->v == x;
    }
    if(root1->v < x) return Search(root->rchild, root1->rchild, x);
    else return Search(root->lchild, root1->lchild, x);
}

bool Judge(Node* root, string s)   //每个测试树的匹配判断函数
{
    Node* root1 = nullptr;
    for(char c : s)
        if(!Search(root, root1, c-'0')) return false;
    return true;
}

int main()
{
    ios::sync_with_stdio(false);
    int n; string s;
    while(cin >> n && n)
    {
        cin >> s;
        Node* root = Create(s);
        while(n--)
        {
            cin >> s; bool f = Judge(root, s);
            cout << (f ? "YES" : "NO") << '\n';
        }
    }
    return 0;
}


发表于 2021-01-22 16:06:28 回复(0)
#include<bits/stdc++.h>
using namespace std;
struct TreeNode
{
    int data;
    TreeNode* leftchild;
    TreeNode* rightchild;
    TreeNode(int x):data(x),leftchild(NULL),rightchild(NULL){} 
};
TreeNode* Insert(TreeNode* root,int x)//递归建树
{
    if(root==NULL)
    {
        root=new TreeNode(x);
    }
    else if(x< root->data)//插入左子树
    {
        root->leftchild=Insert(root->leftchild,x);
    }
    else if(x>root->data)//插入右子树
    {
        root->rightchild=Insert(root->rightchild,x);
    }
    return root;
}
//前序遍历和中序遍历可以唯一确定一棵二叉树,而对二叉排序树而言,相同元素的二叉排序树中序遍历一定相同,
//而不同元素二叉排序树使用前序遍历就可以发现不相同,所以只需要前序遍历两个二叉树,
bool judge(TreeNode* root1,TreeNode* root2)//判断两二叉搜索树是否相等
{
    if(root1==NULL&&root2==NULL)
        return true;
    else if((root1!=NULL&&root2==NULL)||(root1==NULL&&root2!=NULL))
            return false;
    else if(root1!=NULL&&root2!=NULL)
    {
        if(root1->data==root2->data)
        {
           return judge(root1->leftchild,root2->leftchild)&&judge(root1->rightchild,root2->rightchild);
        }
        else 
            return false;
            
    }
}
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0)
            break;
        string str;
        cin>>str;
        int l=str.size();
        TreeNode* root1=NULL;//建立空树
        for(int i=0;i<l;i++)
        {
            root1=Insert(root1,str[i]);
        }
        for(int i=0;i<n;i++)//n组测试树
        {
            string str1;
            cin>>str1;
            TreeNode* root2=NULL;
            for(int j=0;j<str1.size();j++)
            {
                root2=Insert(root2,str1[j]);
            }
            if(judge(root1,root2))
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
    }
    return 0;
}

发表于 2020-03-31 21:32:35 回复(0)
#include<iostream>   //利用先序+中序或者后序+中序来唯一确定一颗二叉树(BST也是二叉树)的思想
#
include<cstdio>
#include<vector>
using namespace std;
const int maxn=30;
struct node{
    node* lchild;
    node* rchild;
    int data;
};
vector<int> pre,in;       //原始序列的BST的先序和中序序列,全局变量
void insert(node* &root,int data){        //插入函数,建立BST
    if(root==NULL){
        root=new node;
        root->lchild=NULL,root->rchild=NULL;
        root->data=data;
        return;
    }
    if(root->data>data){
        insert(root->lchild,data);
    }
    else insert(root->rchild,data);
}
void pre_order(node* root,vector<int> &vi){      //先序遍历,序列存入vector
    if(root==NULL) return;
    vi.push_back(root->data);
    pre_order(root->lchild,vi);
    pre_order(root->rchild,vi); 
}
void in_order(node* root,vector<int> &vi){       //中序遍历
    if(root==NULL) return;
    in_order(root->lchild,vi);
    vi.push_back(root->data);
    in_order(root->rchild,vi); 
}
int main(){
    int n;
    string origin,temp;
    while(cin >> n){
        if(n==0) break;
        cin >> origin;
        node* root=NULL;
        for(int i=0;i<origin.size();i++) insert(root,origin[i]-'0');      //建立BST
        pre_order(root,pre);          //先序遍历得到pre
        in_order(root,in);          //中序遍历得到in
        for(int i=0;i<n;i++){            //n个查询
            vector<int> pre_temp,in_temp;         //当前查询的先序序列和中序序列
            cin >> temp;
            node* temp_root=NULL;
            for(int i=0;i<temp.size();i++) insert(temp_root,temp[i]-'0');     //当前查询的BST
            pre_order(temp_root,pre_temp);
            in_order(temp_root,in_temp);
            if(pre_temp==pre && in_temp==in) cout << "YES" << endl;     //当且仅当相等
            else cout << "NO" << endl;
        }
    }
    return 0;
}
发表于 2020-03-25 16:32:25 回复(0)
Java
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        String s = preOrderString(scanner.next());
        for (int i = 0; i < n; i++) {
            String s1 = preOrderString(scanner.next());
            System.out.println(s.equals(s1)?"YES":"NO");
        }
    }

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    static void creat(TreeNode root, int v){
        if (v<root.val){
            if (root.left==null) root.left = new TreeNode(v);
            else creat(root.left,v);
        }else {
            if (root.right==null) root.right= new TreeNode(v);
            else creat(root.right,v);
        }
    }
    static void preOrder(TreeNode root,StringBuilder builder) {
        if (root != null) {
            builder.append(root.val);
            preOrder(root.left,builder);
            preOrder(root.right,builder);
        }
    }
    
    static String preOrderString(String s){
        char[] tree = s.toCharArray();
        TreeNode root = new TreeNode(tree[0]);
        for (int i = 1; i < tree.length; i++) creat(root,tree[i]);
        StringBuilder builder = new StringBuilder();
        preOrder(root,builder);
        return builder.toString();
    }
}




编辑于 2020-03-20 09:45:43 回复(0)
不容易啊
#include <stdio.h>
(737)#include <stdlib.h>
#include <math.h>
(865)#include <string.h>
#include <stdbool.h>
typedef struct ne
{
    char data;
    struct ne *lchild;
    struct ne *rchild;
}nb;
nb *ins(nb *root,char c)
{
    if(!root)
    {
        root=(nb *)malloc(sizeof(nb));
        root->data=c;
        root->lchild=root->rchild=NULL;
        return root;
    }
    else if(c<root->data)
    {
        root->lchild=ins(root->lchild,c);
    }
    else if(c>root->data)
    {
        root->rchild=ins(root->rchild,c);
    }
    return root;
}
bool juu(nb *root1,nb *root2)
{
    if(!root1&&!root2)
        return true;
    else if(root1&&root2&&root1->data==root2->data)
    {
        return juu(root1->rchild,root2->rchild)&&juu(root1->lchild,root2->lchild);
    }

    return false;
}
int main()
{
   int n;
while(scanf("%d",&n)!=EOF)
      {
          if(n==0)
            break;
      getchar();
       char s[11];
       gets(s);
       int len=strlen(s);
       int d[n];
       int i;
       nb *root=NULL;
       for(i=0;i<len;i++)
       {
           root=ins(root,s[i]);

       }
       int j;

       for(i=0;i<n;i++)
       {
            char *s1=(char *)malloc(sizeof(char));
           gets(s1);
           nb *root1=NULL;
           for(j=0;j<len;j++)
       {
           root1=ins(root1,s1[j]);
       }
       d[i]=juu(root,root1);
       free(s1);
       free(root1);
       }
      for(i=0;i<n;i++)
      {
          if(d[i]==1)
            printf("YES\n");
          else
            printf("NO\n");
      }
      }
return 0;
}

发表于 2020-03-17 15:52:23 回复(0)
思路:1、先建立初始树t1;
2、建立需要比较的树t2,并且边建立边比较,比如某个结点在树t1中位置是2,而在树t2中位置是3(用完全二叉树的位置关系,左子树位置是父结点位置的两倍,右子树位置是父结点位置的两倍加一),位置不同,马上停止并输出,不用建立完整的第二棵树。
#include <stdio.h>
typedef struct btree
{
    int data;
    struct btree *lc;
    struct btree *rc;
}Btree;
Btree *insert(Btree *t,int x)
{
    if(t==NULL)
    {
        t=(Btree *)malloc(sizeof(Btree));
        t->data=x;
        t->lc=t->lc=NULL;
    }
    else
    {
        if(t->data>x)t->lc=insert(t->lc,x);
        else t->rc=insert(t->rc,x);
    }
    return t;
}
int search(Btree *t,int x,int pos)    //在t==NULL时应该退出,但是本题中一定找得到x的位置
{
    if(t->data==x)return pos;
    else
    {
        if(t->data>x)return search(t->lc,x,2*pos);
        else return search(t->rc,x,2*pos+1);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n) && n!=0)
    {
        char a[11];
        scanf("%s",a);
        Btree *t1=NULL;
        for(int i=0;a[i]!='\0';i++)t1=insert(t1,a[i]-'0');
        for(int i=0;i<n;i++)
        {
            int flag=1;
            scanf("%s",a);
            Btree *t2=NULL;
            for(int j=0;a[j]!='\0';j++)
            {
                t2=insert(t2,a[j]-'0');
                if(search(t1,a[j]-'0',1)!=search(t2,a[j]-'0',1)) //从根结点(1)开始搜索
                {
                    flag=0;
                    break;
                }
            }
            if(flag)printf("YES\n");
            else printf("NO\n");
        }
    }
}
发表于 2020-03-17 10:31:28 回复(0)
两个相同数字的排序二叉树的中序遍历一定是相同的,我们只需要遍历比较两个二叉树的前序遍历或者后序遍历即可,比较每个位置的元素是否相同。
#include <iostream>
(720)#include <cstdint>
#include <cstdio>
(802)#include <cstring>
#include <string>
(765)#include <vector>
#include <queue>
(789)#include <stack>
#include <algorithm>
(831)#include <cmath>
using namespace std;

/* 
    判断两个二叉搜索树是不是相同

    input:
        2
        567432
        543267
        576342
        0
    output:
        YES
        NO
 */

struct Node
{
    int data;
    Node *leftChild;
    Node *rightChild;
    Node(int _data) : data(_data), leftChild(NULL), rightChild(NULL) {}
};

Node *Insert(Node *root, int x)
{
    if (root == NULL)
    {
        root = new Node(x);
    }
    else if (x < root->data)
    {
        root->leftChild = Insert(root->leftChild, x);
    }
    else
    {
        root->rightChild = Insert(root->rightChild, x);
    }
    return root;
}

int posi;

void PreOrder(Node *root, int seq[])
{
    if (root == NULL)
    {
        return;
    }
    seq[posi++] = root->data;
    PreOrder(root->leftChild, seq);
    PreOrder(root->rightChild, seq);
    return;
}

int main()
{
    freopen("data.txt", "r", stdin);
    int n;
    while (scanf("%d", &n) != EOF)
    {
        if (n == 0)
            break;
        // 构造第一棵二叉树
        Node *root = NULL;
        char str[10];
        scanf("%s", str);
        int len = strlen(str);
        for (int i = 0; i < len; i++)
        {
            int x = str[i] - '0';
            root = Insert(root, x);
        }
        posi = 0;
        int seq1[10] = {-1};
        PreOrder(root, seq1);
        for (int i = 0; i < n; i++)
        {
            Node *root1 = NULL;
            char str1[10];
            scanf("%s", str1);
            int len = strlen(str1);
            for (int i = 0; i < len; i++)
            {
                int x = str1[i] - '0';
                root1 = Insert(root1, x);
            }      
            bool flag = true;
            int seq2[10] = {-1};
            posi = 0;
            PreOrder(root1, seq2);
            for (int  i = 0; i < posi; i++)
            {
                if(seq1[i] != seq2[i]) {
                    flag = false;
                    break;
                }
            }
            if(flag) {
                printf("YES\n");
            }else {
                printf("NO\n");
            }
        }
    }
    return 0;
}


发表于 2020-02-29 13:50:23 回复(0)
中序+先序(后序)可以唯一确定一颗二叉树,而对于同一个数字集合不同排列构造的二叉排序树中序序列一定是相同的,因此只需比较先序序列
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

const int maxn=105;
struct node
{
	char data;
	node *lchild,*rchild;
	node()
	{
		lchild=rchild=NULL;
	}
};
void insert(node *&t,int x)
{
	if(!t)	
	{
		t=new node;
		t->data=x;
		return;
	}
	if(t->data>x)	insert(t->lchild,x);
	else  insert(t->rchild,x);
}
void preorder(node *t,string &s)
{
	if(t)
	{
		s+=t->data;
		preorder(t->lchild,s);
		preorder(t->rchild,s);
	}
}
int main()
{
	int n;
	while(cin>>n&&n)
	{
		node *t1=NULL;
		string s,pre1;
		cin>>s;
		for (int i=0;i<s.size();++i)
		{
			insert(t1,s[i]);
		}
		preorder(t1,pre1);
		for (int i=0;i<n;++i)
		{
			cin>>s;
			node *t2=NULL;
			string pre2;
			for (int j=0;j<s.size();++j)
			{
				insert(t2,s[j]);
			}
			preorder(t2,pre2);
			if(pre1==pre2)	cout<<"YES\n";
			else  cout<<"NO\n";
		}
	}
	return 0;
}


发表于 2020-01-13 11:34:02 回复(0)
  • 搜索二叉树构建
  • 确定该二叉树前序中序遍历结果
  • 比较两个遍历结果是否相同确定二叉树是否相同。

代码如下:

#include<stdio.h>
#include<string.h>
struct Node
{
    char d;
    struct Node * lchild;
    struct Node * rchild;
}tree[100];
int allocate = 0;

struct Node * insert(struct Node * root, char d)
{
    if (root == NULL) 
    {
        struct Node * newNode = &tree[allocate++];
        newNode->d = d;
        newNode->lchild = NULL;
        newNode->rchild = NULL;
        return newNode;        
    }
    if (root->d > d) root->lchild = insert(root->lchild, d);
    else root->rchild = insert(root->rchild, d);
    return root;
}

char * str;
int count;

void preOrder(struct Node * root)
{
    str[count++] = root->d;
    if (root->lchild != NULL) preOrder(root->lchild);
    if (root->rchild != NULL) preOrder(root->rchild);
}

void inOrder(struct Node * root)
{
    if (root->lchild != NULL) inOrder(root->lchild);
    str[count++] = root->d;
    if (root->rchild != NULL) inOrder(root->rchild);
}

int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        if (n == 0) break;
        allocate = 0;
        char str1[20];
        scanf("%s", &str1);
        int len = strlen(str1);
        struct Node * root = NULL;
        int i;
        for (i = 0; i < len; i++) root = insert(root, str1[i]);
        char seq[20];
        str = seq;
        count = 0;
        preOrder(root); inOrder(root); str[count] = 0;
        int temp = allocate;
        for (i = 0; i < n; i++)
        {
            allocate = temp;
            char str2[20];
            scanf("%s", str2);
            int len2 = strlen(str2);
            struct Node * root2 = NULL;
            int j;
            for (j = 0; j < len2; j++) root2 = insert(root2, str2[j]);
            char seq2[20];
            str = seq2;
            count = 0;
            preOrder(root2); inOrder(root2); str[count] = 0;
            if (strcmp(seq, seq2) == 0) printf("YES\n");
            else printf("NO\n");
        }    
    }
    return 0;
}
发表于 2019-08-05 10:38:45 回复(0)
#include <iostream>
#include <string>

using namespace std;


struct node {
  char val;
  node *left;
  node *right;
  node(int val='0', node* left=nullptr, node* right=nullptr): val(val), left(left), right(right) {}
};

node* insert_bst(node* root, char c) {
  node* newnode;
  if(root == nullptr) {
    newnode = new node(c);
  }
  else if(c > root->val) {
    newnode = insert_bst(root->right, c);
    if(root->right == nullptr) {
      root->right = newnode;
    }
  }
  else {
    newnode = insert_bst(root->left, c);
    if(root->left == nullptr) {
      root->left = newnode;
    }
  }
  return newnode;
}

node* build_bst(string s) {
  if(s.size() == 0) return nullptr;
  node* root = new node(s[0]);
  for(auto c : s.substr(1)) {
    insert_bst(root, c);
  }
  return root;
}

bool identical(node* a, node* b) {
  if(a == nullptr && b == nullptr) {
    return true;
  }
  if(a == nullptr || b == nullptr) {
    return false;
  }
  if(a->val != b->val) {
    return false;
  }
  bool left = identical(a->left, b->left);
  if(!left) return false;
  return identical(a->right, b->right);
}

int main() {
  int n;
  while(cin >> n) {
    if(n == 0) break;
    string ref, s;
    cin >> ref;
    node* refx = build_bst(ref);
    while(n--) {
      cin >> s;
      node* x = build_bst(s);
      if(identical(refx, x)) {
        cout << "YES\n";
      }
      else {
        cout << "NO\n";
      }
    }
  }
  return 0;
}
有树在直接比较树就行了,干嘛还遍历再去比较字符串?
发表于 2019-01-17 09:28:56 回复(0)
仔细看题的话,其实数据长度并不长,用一个数组来表示完全数,然后向里面填数,最后只需要比较数组是否一样就可以了,相比建立结点类型要方便很多。
#include<stdio.h>
#include<string.h>
using namespace std;
int node[500];
int now[500];
char line[10];
void insert(int x,int a[],int i){
    if(x<a[i]){
        if(a[2*i]==-1){
            a[2*i]=x;
        }else{
            insert(x,a,2*i);
        }
    }else{
        if(a[2*i+1]==-1){
            a[2*i+1]=x;
        }else{
            insert(x,a,2*i+1);
        }
    }
}
int main(){
    int n;
    for(int i=0;i<500;i++){
        node[i]=-1;
    }
    scanf("%d\n",&n);
    scanf("%s",line);
    int len=strlen(line);
    for(int i=0;i<len;i++){
        int temp=line[i]-'0';
        insert(temp,node,0);
    }
    char new_line[10];
    while(scanf("%s",new_line)!=EOF){
        if(new_line[0]=='0'){
            break;
        }
        for(int i=0;i<500;i++){
            now[i]=-1;
        }
        int len1=strlen(new_line);
        for(int i=0;i<len1;i++){
        int temp=new_line[i]-'0';
        insert(temp,now,0);
        }
        if(len1!=len){
            printf("NO\n");
            continue;
        }
        bool same=true;
        for(int i=1;i<500;i++){
            if(now[i]!=node[i]){
                same=false;
                break;
            }
        }
        if(same){
            printf("YES\n");
        }else{
            printf("NO\n");
        }
    }
}

发表于 2018-08-29 10:29:40 回复(0)
#include<cstdio>
#include<cstring>
int n,root;
int lchild[10];
int rchild[10];
int  root1;
int lchild1[10];
int rchild1[10];
char in[11];
#pragma warning(disable:4996)
void build(int num,int pre) {     if (num < pre) {         if (lchild[pre] == -1)lchild[pre] = num;         else build(num, lchild[pre]);     }     else {         if (rchild[pre] == -1)rchild[pre] = num;         else build(num, rchild[pre]);     }
}
void build1(int num, int pre) {     if (num < pre) {         if (lchild1[pre] == -1)lchild1[pre] = num;         else build1(num, lchild1[pre]);     }     else {         if (rchild1[pre] == -1)rchild1[pre] = num;         else build1(num, rchild1[pre]);     }
}
int main() {     freopen("in.txt", "r", stdin);     while (scanf("%d", &n) != EOF &&n) {         for (int i = 0; i < 10; i++) lchild[i] = rchild[i] = -1;         scanf("%s", in);         root = in[0] - '0';         for (int i = 1; i < strlen(in);i++) {             int node = in[i] - '0';             build(node, root);         }         for (int i = 0; i < n; i++) {             for (int j = 0; j < 10; j++) lchild1[j] = rchild1[j] = -1;             scanf("%s", in);             root1 = in[0] - '0';             for (int j = 1; j < strlen(in); j++) {                 int node = in[j] - '0';                 build1(node, root1);             }             int flag = 1;             for (int j = 0; j < 10; j++) {                 if (lchild[j] != lchild1[j] || rchild[j] != rchild1[j]) {                     flag = 0;                     break;                 }             }             if (flag == 0)printf("NO\n");             else printf("YES\n");         }     }     return 0;
}

两次建树过程,只保存左右孩子数组。比较两个树的数组是否相等即可

发表于 2018-06-13 22:51:42 回复(0)
#include<stdio.h>
#include<string.h>
struct Node{
 Node *lchild;
 Node *rchild;
 int c;
}Tree[110];
int loc;
Node *creat(){//申请空间 
  Tree[loc].lchild=Tree[loc].rchild=NULL;
  return &Tree[loc++]; 
} 
char str1[30],str2[30];//包括中序在内的两种遍历可以确定唯一棵二叉树,
      //所以可以将前序和中序字符串连接之后进行比较
      
int size1,size2;//保存字符串个数
char *str;//当前正在保存的字符串
int *size;//当前正在保存的字符个数 

void preorder(Node *T){//前序 
 str[(*size)++]=T->c+'0'; 
 if(T->lchild!=NULL)
 {
 preorder(T->lchild);
 }
 if(T->rchild!=NULL)
 {
 preorder(T->rchild);
 }
 }
 void inorder(Node *T){//中序 
 if(T->lchild!=NULL)
 {
 inorder(T->lchild); 
 }
 str[(*size)++]=T->c+'0'; 
 if(T->rchild!=NULL)
 {
 inorder(T->rchild);
 }
 }
 Node *insert(Node *T,int x) {//插入数字
 if(T==NULL)
 {
 T=creat();
 T->c=x;
 return T;
 } 
 else if(x<T->c)
 {
 T->lchild=insert(T->lchild,x);
 }
 else if(x>T->c)
 {
 T->rchild=insert(T->rchild,x);
 }
 return T;
 }
 int main(){
 int n;
 char x[12];
 while(scanf("%d",&n)!=EOF&&n!=0){
 loc=0;//初始化静态空间
 Node *T=NULL;
 scanf("%s",x);
 for(int i=0;x[i]!=0;i++)
 {
 T=insert(T,x[i]-'0');
 }
 size1=0;
 str=str1;
 size=&size1;
 preorder(T);
 inorder(T);
 str1[size1]=0;//结尾添加空字符
 while(n--!=0) {//输入n个其他字符串 
 scanf("%s",x);
 Node *T2=NULL;
 for(int i=0;x[i]!=0;i++)
 {
 T2=insert(T2,x[i]-'0');
 }
 size2=0;
 str=str2;
 size=&size2;
 preorder(T2);
 inorder(T2);
 str2[size2]=0;//结尾添加空字符
 puts(strcmp(str1,str2)==0?"YES":"NO"); 
 }
 }
 return 0;
 }

编辑于 2018-04-01 13:59:53 回复(0)

二叉搜索树即二叉排序树,要判断两棵树是否一致,可用:
(1)判断前序+中序遍历结果是否一致
(2)判断后序+中序遍历结果是否一致
两种方法来判断
又因为二叉排序树中序遍历的结果是所有数递增的结果,所以只需判断前序或后序遍历结果是否一致即可(这里判断的是前序遍历结果)

#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct BiNode{
    struct BiNode *lchild, *rchild;
    char e;
}BiNode, *BiTree;

void Insert(BiTree *T, char c)  //构造二叉排序树
{
    if((*T)==NULL)
    {
         (*T) = (BiNode *)malloc(sizeof(BiNode));
         (*T)->e = c;
         (*T)->lchild = NULL;
         (*T)->rchild = NULL;
    }
    else{
        if(c==(*T)->e) return ;
        if(c>(*T)->e) Insert(&(*T)->rchild, c);
        else Insert(&(*T)->lchild, c);
    }
}
string PreOrder(BiTree T)  //将二叉树的前序遍历结果存放在一个字符串中
{
    string str = "";
    if(T!=NULL)
    {
        str+=T->e;
        str+=PreOrder(T->lchild);
        str+=PreOrder(T->rchild);
    }
    return str;
}
bool cmp(BiTree T, BiTree T1)  //比较两个二叉搜索树的前序遍历结果是否一样
{
    string str1 = PreOrder(T);
    string str2 = PreOrder(T1);
    if(str1==str2) return true;
    return false;
}
void Delete(BiTree *T)  //销毁二叉树,释放其申请的空间
{
    if((*T)->lchild==NULL && (*T)->rchild == NULL)
    {
        free(*T);
        *T = NULL;
    }
    else{
        if((*T)->lchild!=NULL)
        {
            Delete(&(*T)->lchild);
        }
        if((*T)->rchild!=NULL)
        {
            Delete(&(*T)->rchild);
        }
    }
}
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0) return 0;
        string str, strtmp;
        cin>>str;
        BiTree T = NULL, T1 = NULL;
        for(int i = 0; i<str.length(); i++)  //对参考字符串构造二叉排序树
            Insert(&T, str[i]);
        for(int i = 0; i<n; i++)
        {
            cin>>strtmp;
            for(int i = 0; i<strtmp.length(); i++)  //对待判断的字符串构造二叉排序树
                Insert(&T1, strtmp[i]);
            if(cmp(T, T1)) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
            Delete(&T1);
            T1 = NULL;
        }
    }
    return 0;
}
发表于 2018-03-09 20:57:00 回复(0)
这个题给惦记好几天了。难度在于将两个排序二叉树生成后如何判断两个排序二叉树是否是相同的?网上查阅了一个博客,最后得出的结论是只要两个排序二叉树的前序遍历(当然后序遍历也可以,但是中序遍历不行)相同,那么他们俩就是相同的,有了这个思路后就先构造排序二叉树,然后比较中序遍历就OK了。我的代码略混乱,分享自己的代码和博客代码。
自己的代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>

typedef struct Node{
    int key;
    struct Node *left;
    struct Node *right;
}Node;
///申请一个树的根节点,并将其初始设置为空
Node * Tree=NULL,* p,* temp_p;
char tempa[12],tempb[12],temp_str[12];

int length,i;
///先将对应的二叉树构造出来
void Creat(char* temp){
        for(i=0;i<strlen(temp);i++){
                p=(Node *)malloc(sizeof(Node));
                p->key=temp[i]-'0';
                p->left=p->right=NULL;

                if(Tree==NULL){
                    Tree=p;
                }else{
                    temp_p=Tree;
                    while(1){
                        if(temp_p->key==p->key)break;
                        else if(temp_p->key<p->key){
                                if(temp_p->right==NULL){
                                    temp_p->right=p;
                                    break;
                                }else
                                    temp_p=temp_p->right;
                            }else
                                if(temp_p->key>p->key){
                                    if(temp_p->left==NULL){
                                    temp_p->left=p;
                                    break;
                                }else
                                    temp_p=temp_p->left;
                            }
                        }
                    }
                }
}

void pre_order(Node* Tree){
    ///使用前应当将长度设置为0初始化
    if(Tree==NULL)return;
    else{
        temp_str[length++]=(char)(Tree->key+'0');
        //printf("+%c",temp_str[length-1]);
        pre_order(Tree->left);
        pre_order(Tree->right);
    }
}
int main()
{
    int T;
    while(scanf("%d",&T)!=EOF){
        if(0==T)break;
        scanf("%s",tempa);
        Tree=NULL;
        ///先将对应的二叉树构造出来
        Creat(tempa);

        ///对构造好的排序二叉树进行前序遍历进行唯一性标识
        length=0;
        pre_order(Tree);
        strcpy(tempa,temp_str);

        ///上边已经将二叉树构造好了,现在只要进行一个判断的工作就ok
        while(T--){
            scanf("%s",tempb);
            Tree=NULL;

            ///先将对应的二叉树构造出来
            Creat(tempb);

        ///对构造好的排序二叉树进行前序遍历进行唯一性标识
        length=0;
        pre_order(Tree);
        strcpy(tempb,temp_str);

            if(strcmp(tempa,tempb))printf("NO\n");
            else printf("YES\n");
    }
    }
    return 0;
}

发表于 2017-01-08 11:52:47 回复(0)