• 判断是否为同一颗搜索树 C/C++


    1.问题描述:给定一个插入序列就可以唯一确定一颗二叉搜索树;然而,一颗给定的二叉搜索树却可以由不同的插入序列而得到。对于输入的各种插入序列,判断能否生成一样的二叉搜索树。


    2.求解思路:

    • 分别建两棵树的判别方法
    • 不建树的判别方法
    • 建一棵树,再判别其他序列是否与该树一致

    2.1 分别建两棵树的判别方法:分别建两棵树,再判别树是否一样(用递归方法实现)。

    2.2 不建树的判别方法:

            已知给定的序列第一个元素是二叉搜索树的根结点,那么剩下的元素就可以分为俩个集合比根结点大的元素比根节点小的元素(要保持原来的相对顺序)。再递归的对两个序列左右集合(子序列)做相同的操作,直到两个序列对应的左子集或右子集元素不相同。

                            (1)判断第一个元素(根结点)是否相同

                            (2)将比根结点小的元素依次放入新的集合A;比根结点大的依次放入B(同理另一个序列放入A1,B1)

                            (3)若A 、 A1 为空,且B、B1为空,则两个序列为同一颗树,结束退出;否则(4)

                            (4)(A==A1)&&(B==B1)为真则将A和A1、B和B1分别作为新的待比较序列传入(1),假则(5)

                            (5)两个序列所表示的树不等,结束退出

    2.3 建一棵树,再判别其他序列是否与该树一致:在建好的树T中依次查找新序列中的每个元素

    • 如果每次搜索所经过的结点(不包括目标结点)均在前面出现过,则一致
    • 否则(某次搜索中遇到前面未出现的结点),则不一致

    2.3.2 代码实例:

    #include<cstdio> 
    #include<cstdlib> 
    typedef struct TreeNode *Tree;
    struct TreeNode {
    	int v;
    	Tree Left, Right;
    	int flag;
    };
    Tree NewNode( int V )
    {
    	Tree T = (Tree)malloc(sizeof(struct TreeNode));
    	T->v = V;
    	T->Left = T->Right = NULL;
    	T->flag = 0;
    	return T;
    }
    Tree Insert( Tree T, int V )
    {
    	if ( !T ) T = NewNode(V);
    	else {
    		if ( V>T->v )
    			T->Right = Insert( T->Right, V );
    		else
    			T->Left = Insert( T->Left, V );
    	}
    	return T;
    }
    Tree MakeTree( int N )
    { 
    	Tree T;
    	int i, V;
    	scanf("%d", &V);
    	T = NewNode(V);
    	for (i=1; i<N; i++) {
    		scanf("%d", &V);
    		T = Insert(T, V);
    	}
    	return T;
    }
    int check ( Tree T, int V )
    {
    	if ( T->flag ) {
    	if ( V<T->v ) return check(T->Left, V);
    		else if ( V>T->v ) return check(T->Right, V);
    		else return 0;
    	}
    	else {
    		if ( V==T->v ) {
    			T->flag = 1;
    			return 1;
    		}
    	else return 0;
    	}
    }
    int Judge( Tree T, int N )
    {
    	int i, V, flag = 0;
    	/* flag: 0代表目前还一致,1代表已经不一致*/
    	scanf("%d", &V);
    	if ( V!=T->v ) flag = 1;
    	else T->flag = 1;
    	for (i=1; i<N; i++) {
    		scanf("%d", &V);
    		if ( (!flag) && (!check(T, V)) ) flag = 1;
    	}
    	if (flag) return 0;
    	else return 1;
    }
    void ReSetT(Tree T){
    	T->flag = 0;
    	if(T->Left != NULL)	ReSetT(T->Left);
    	if(T->Right != NULL) ReSetT(T->Right);
    }
    int main()
    { 
    	int N, L, i;
    	Tree T;
    	scanf("%d", &N);
    	while (N) {
    		scanf("%d", &L);
    		T = MakeTree(N);
    		for (i=0; i<L; i++) {
    			if (Judge(T, N)) printf("Yes
    ");
    			else printf("No
    ");
    			ReSetT(T); /*清除T中的标记flag*/
    		}
    		scanf("%d", &N);
    	}
    	return 0;
    }

  • 相关阅读:
    Tidy 一个把HTML 转成XHTML的工具库[整理]
    HTTP详解(转载)
    C#中各种验证方法(数字,邮件,电话,传真,邮政编码,网络地址)和自动编号的
    常用Visual C# 快捷键
    c#中字符串截取使用的方法
    C#将相片转换成二进制存储在数据库中,再从数据库中显示出来
    用长按键重复输入 Mac OS X Lion
    Unsupported major.minor version 51.0解决办法
    XCode4.3.2 没有Command Line Utility选项
    IBM高级工程师,谷歌等国际知名公司工程师撰写Android开发教程合集
  • 原文地址:https://www.cnblogs.com/long98/p/10352234.html
Copyright © 2020-2023  润新知