数据结构实验之查找一:二叉排序树 SDUT 二叉排序树的建立与判断 (与删除)

数据结构实验之查找一:二叉排序树

Time Limit: 400MS Memory limit: 65536K

题目描述

对应给定的一个序列可以唯一确定一棵二叉排序树。然而,一棵给定的二叉排序树却可以由多种不同的序列得到。例如分别按照序列{3,1,4}和{3,4,1}插入初始为空的二叉排序树,都得到一样的结果。你的任务书对于输入的各种序列,判断它们是否能生成一样的二叉排序树。

输入

输入包含若干组测试数据。每组数据的第1行给出两个正整数N (n < = 10)和L,分别是输入序列的元素个数和需要比较的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列生成一颗二叉排序树。随后L行,每行给出N个元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。

输出

对每一组需要检查的序列,如果其生成的二叉排序树跟初始序列生成的二叉排序树一样,则输出"Yes",否则输出"No"。

示例输入

4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0

示例输出

Yes
No
No

提示

      //附加:::::

在二叉排序树中删去一个结点,分三种情况讨论:

 1.若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。

 2.若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉排序树的特性。

 3.若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整。比较好的做法是,找到*p的直接前驱(或直接后继)*s,用*s来替换结点*p,然后再删除结点*s。

数据结构实验之查找一:二叉排序树 SDUT 二叉排序树的建立与判断 (与删除)_第1张图片



/* 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点, */
/* 并返回TRUE;否则返回FALSE。 */
Status DeleteBST(BiTree *T,int key)
{ 
    if(!T) /* 不存在关键字等于key的数据元素 */ 
        return FALSE;
    else
    {
        if (key==T->data) /* 找到关键字等于key的数据元素 */ 
            return Delete(T);
        else if (keydata)
            return DeleteBST(T->lchild,key);
        else
            return DeleteBST(T->rchild,key);
         
    }
}

/* 从二叉排序树中删除结点p,并重接它的左或右子树。 */
Status Delete(BiTree *p)
{
    BiTree *q,*s;
    if(p->rchild==NULL) /* 右子树空则只需重接它的左子树(待删结点是叶子也走此分支) */
    {
        q=p; p=p->lchild; free(q);
    }
    else if(p->lchild==NULL) /* 只需重接它的右子树 */
    {
        q=p;p=p->rchild; free(q);
    }
    else /* 左右子树均不空 */
    {
        q=p; s=p->lchild;
        while(s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */
        {
            q=s;
            s=s->rchild;
        }
        p->data=s->data; /*  s指向被删结点的直接前驱(将被删结点前驱的值取代被删结点的值) */
        if(q!=p)
            q->rchild=s->lchild; /*  重接q的右子树 */ 
        else
            q->lchild=s->lchild; /*  重接q的左子树 */
        free(s);
    }
    return TRUE;
}


 代码风格一
#include
using namespace std;
int n,m,a[1000100],num=0;
struct node
{
    int data;
    node *L,*R;
};
node *Creat()
{
    node *p=new node;
    p->L=NULL;
    p->R=NULL;
    return p;
}
void BSTInsert(node *&root,int element)   //插入算法
{
    if(root==NULL)
    {
        root=Creat();
        root->data=element;
        return ;
    }
    if(elementdata)
        BSTInsert(root->L,element);
    else
        BSTInsert(root->R,element);
    return ;
}
void Build(node *&root)            //创建二叉树
{
    root=NULL;                //勿忘,否则没法插入第一个元素。
    for(int i=0;idata);
//        mid(p->L);
//        mid(p->R);
//    }
//}
int Judge(node* root,node *Root)
{
    if(!root&&!Root)
        return 1;
    if(root&&Root)
    {
        if(root->data!=Root->data)
            return 0;
        if(Judge(root->L,Root->L)&&Judge(root->R,Root->R))
        {
            num++;
        }
        else
            return 0;
    }
    else
        return 0;
}
int main()
{
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        scanf("%d",&m);
        for(int i=0;i

///新代码风格。。、
#include
#define bug() puts("*****************");
using namespace std;
const int maxn = 1100;
int n,m,top=0;
int a[100],temp[100];
struct node{
	int val;
	node *L,*R;
};
node *Create(int elem){
	node *p=new node;
	p->val=elem;
	p->L=p->R=NULL;
	return p;
}
void Build(node *&p,int elem){
	if(!p) p=Create(elem);
	else {
		if(p->val>elem) Build(p->L,elem);
		else Build(p->R,elem);
	}
}
bool judge(node *root,node *p){
	if(!root&&!p) return true;
	if(p&&root) return root->val==p->val&&judge(root->L,p->L)&&judge(root->R,p->R);
	return false;
}
int main(){
	top=0;
  while(scanf("%d",&n),n){
	scanf("%d",&m);
	node *root=NULL;
	for(int i=0;i



你可能感兴趣的:(树类,----数据结构----)