SDUT OJ 二叉排序树

二叉排序树序列判断
本文介绍了一种通过比较两个序列来判断它们是否能够构成相同的二叉排序树的方法。使用递归方式创建二叉树,并通过先序遍历获得序列,最终比较两个序列是否相同以确定是否为同一棵树。

二叉排序树

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic Discuss

Problem Description

二叉排序树的定义是:或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 今天我们要判断两序列是否为同一二叉排序树

Input

开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。

接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉排序树。

接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉排序树。(数据保证不会有空树)

Output

 

Sample Input

2
123456789
987654321
432156789
0

Sample Output

NO
NO

Hint

 

Source

#include <iostream>


#include <cstdio>
#include <cstdlib>
#include<cstring>
using namespace std;
typedef struct st
{
    char data;
    struct st *l,*r;
} tree;

char a[20],b[20],c[20];
int k;
 void creat(tree *&t,int e)//前面是说T是一个指向结构体的指针类型。‘&’在此应该是C++的引用,是函数操作可以改变T
                          //T是指针 如果不加&的话,函数体内对T赋值就会失败,因为是传的“值”,T不会改变,形参的变化不会传给实参
{
    if(t==NULL)
    {
        t=(tree *)malloc(sizeof(tree));
        t->data=e;
        t->l=NULL;
        t->r=NULL;
    }
    else
    {
        if(e<=t->data)
        {
            creat(t->l,e);
        }
        else creat(t->r,e);
    }


}
void first(tree *t)
{
    if(t)
    {
        b[k++]=t->data+'0';
        first(t->l);
        first(t->r);
    }
}
int main()
{
    tree *t;
    int n;
    while(scanf("%d",&n)!=EOF)
    {if(n==0)break;

        t=NULL;k=0;
        scanf("%s",a);
        int len=strlen(a);
        int i;
        for(i=0; i<len; i++)
        {
            a[i]=a[i]-'0';
            creat(t,a[i]);
        }
        first(t);
        int flag,j;
        for(i=0; i<n; i++)
        {
            flag=1;
            scanf("%s",c);
            for(j=0; j<len; j++)
            {
                if(c[j]!=b[j])
                {
                    flag=0;
                    break;
                }}
                if(flag)printf("YES\n");
                else printf("NO\n");

        }
    }
    return 0;
}

 

9.25实现下列函数: int Search(SSTable s, KeyType k); /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ 静态查找表的类型SSTable定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct { ElemType *elem; int length; } SSTable; int Search(SSTable a, KeyType k) /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ { int i; if(a.length==0) return ERROR; //先判断a是否为空 a.elem[a.length+1].key=k; for(i=1;a.elem[i].key>k;i++) if(i>=a.length||a.elem[i].key<k) //不能忽略i=a.length这种情况 return ERROR; return i; } /* { int i; a.elem[a.length+1].key=k; for(i=1;a.elem[i].key>k;i++) if(i>a.length||a.elem[i].key<k) return ERROR; return i; } */ 9.26② 试将折半查找算法改写成递归算法。 实现下列函数: int BinSearch(SSTable s, int low, int high, KeyType k); /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ 静态查找表的类型SSTable定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct { ElemType *elem; int length; } SSTable; int BinSearch(SSTable s, int low, int high, KeyType k) /* Index the element which key is k */ /* in StaticSearchTable s. */ /* Return 0 if x is not found. */ { int mid; if(low<=high) { mid=(low+high)/2; if(s.elem[mid].key==k) return mid; if(s.elem[mid].key<k) return BinSearch(s,mid+1,high,k); if(s.elem[mid].key>k) return BinSearch(s,low,high-1,k); } return 0; } /* { int mid; if(low<=high) { mid=(low+high)/2; if(s.elem[mid].key<k) return BinSearch(s,mid+1,high,k); else return BinSearch(s,low,high-1,k); } return 0; } */ 9.31④ 试写一个判别给定二叉树是否为二叉排序树的算法,设此二叉树以二叉链表作存储结构。且树中结点的关键字均不同。 实现下列函数: Status IsBSTree(BiTree t); /* 判别给定二叉树t是否为二叉排序树。*/ /* 若是,则返回TRUE,否则FALSE */ 二叉树的类型BiTree定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct BiTNode { ElemType data; BiTNode *lchild,*rchild; }BiTNode, *BiTree; KeyType predt=-32767; Status IsBSTree(BiTree t) /* 判别给定二叉树t是否为二叉排序树。*/ /* 若是,则返回TRUE,否则FALSE */ { if( t )//&& ! ( t->lchild || t->rchild ) )//空树和叶子不用判断 { if( t->lchild && ( t->data.key < t->lchild->data.key ) )//左孩子不空,左孩子的key比本身的大 return FALSE; else if( t->rchild && ( t->data.key > t->rchild->data.key ) )//右孩子不空,右孩子的key比本身的大 return FALSE; else if( !IsBSTree( t->lchild ) )//判断左子树 return FALSE; else if( !IsBSTree( t->rchild ) )//判断右子树 return FALSE; } return TRUE; } /* { if(!t) return OK; if(t&&!t->lchild&&!t->rchild) return OK; else { if(t->lchild->data.key<t->data.key) IsBSTree(t->lchild); if(t->lchild->data.key>=t->data.key) return ERROR; if(t->rchild->data.key>t->data.key) IsBSTree(t->rchild); else return ERROR; return OK; } } */ 9.33③ 编写递归算法,从大到小输出给定二叉排序树中所有关键字不小于x的数据元素。要求你的算法的时间复杂度为O(log2n+m),其中n为排序树中所含结点数,m为输出的关键字个数。 实现下列函数: void OrderOut(BiTree t, KeyType x, void(*visit)(TElemType)); /* Output is to use visit(t->data); */ 二叉树的类型BiTree定义如下: typedef struct { KeyType key; ... ... // 其他数据域 } ElemType; typedef struct BiTNode { ElemType data; BiTNode *lchild,*rchild; }BiTNode, *BiTree; void OrderOut(BiTree t, KeyType x, void(*visit)(TElemType)) /* Output is to use visit(t->data); */ { if(t->rchild) OrderOut(t->rchild,x,visit); if(t->data.key>=x) visit(t->data); if(t->lchild)OrderOut(t->lchild,x,visit); } /* { if(t->rchild) OrderOut(t->rchild,x); if(t->data<x) exit(); visit(x); if(t->lchild)OrderOut(t->lchild,x); } */ 9.44④ 已知某哈希表的装载因子小于1,哈希函数 H(key)为关键字(标识符)的第一个字母在字母表中的序号,处理冲突的方法为线性探测开放定址法。试编写一个按第一个字母的顺序输出哈希表中所有关键字的算法。 实现下列函数: void PrintKeys(HashTable ht, void(*print)(StrKeyType)); /* 依题意用print输出关键字 */ 哈希表的类型HashTable定义如下: #define SUCCESS 1 #define UNSUCCESS 0 #define DUPLICATE -1 typedef char StrKeyType[4]; typedef struct { StrKeyType key; void *any; } HElemType; int hashsize[] = { 7,11,17,23,29,37,47 }; typedef struct { HElemType elem[MAXLEN]; int count; int sizeindex; } HashTable; int H(char *s)//求Hash函数 { if( s[0] ) return s[0]-'A'+1; //求关键字第一个字母的字母序号(小写) else return 0; } void PrintKeys(HashTable ht, void(*print)(StrKeyType)) /* 依题意用print输出关键字 */ { int i,j; for( i = 1; i <= 26; i++ ) { for( j = (i-1)%hashsize[ht.sizeindex]; ht.elem[j].key[0]; ) { if( H ( ht.elem[j].key ) == i ) print(ht.elem[j].key); j = (j+1)%hashsize[ht.sizeindex]; } } } /* void PrintKeys(HashTable ht, void(*print)(StrKeyType)) /* 依题意用print输出关键字 { int i,j; for(i=1;i<=26;i++) for(j=i;ht.elem[j].key;j=(j+1)%MAXLEN) if(H(ht.elem[j].key)==i) print(ht); } int H(char *s) { if(s) return s[0]-96; else return 0; } */ 9.45③ 假设哈希表长为m,哈希函数为H(x),用链地址法处理冲突。试编写输入一组关键字并建造哈希表的算法。 实现下列函数: int BuildHashTab(ChainHashTab &H, int n, HKeyType es[]) /* 直接调用下列函数 */ /* 哈希函数: */ /* int Hash(ChainHashTab H, HKeyType k); */ /* 冲突处理函数: */ /* int Collision(ChainHashTab H, HLink &p); */ { int i = 0,l,flag; HLink p,node; while( es[i] ) { l = Hash( H, es[i] ); node = ( HLink )malloc( sizeof( HNode ) ); node->data = es[i]; node->next = NULL; i++; if( !H.elem[l] ) H.elem[l] = node; else { flag = 0; p = H.elem[l]; if( p->data == node->data ) flag = 1; while( Collision( H, p ) ) if( p->data == node->data ) { flag = 1; break; } if( !flag ) { p = H.elem[l]; node->next = p; H.elem[l] = node; } } } } "+userLink+""; $('miniAd').show(); } }, onFailure: function(){} }}); } showMiniAd();
SDUT-OJ(Software Development University of Tsinghua Online Judge)是一个在线编程平台,提供给清华大学软件学院的学生和爱好者练习和解决算法问题的环境,其中包括各种计算机科学题目,包括数据结构、算法、图形等。对于"最小生成树"(Minimum Spanning Tree, MST)问题,它是图论中的经典问题,目标是从一个加权无向图中找到一棵包含所有顶点的树,使得树的所有边的权重之和最小。 在C语言中,最常见的是使用Prim算法或Kruskal算法来求解最小生成树。Prim算法从一个顶点开始,逐步添加与当前生成树相连且权重最小的边,直到所有顶点都被包含;而Kruskal算法则是从小到大对所有边排序,每次选取没有形成环的新边加入到树中。 如果你想了解如何用C语言实现这些算法,这里简单概括一下: - 通常使用优先队列(堆)来存储边和它们的权重,以便快速查找最小值。 - 从任意一个顶点开始,遍历与其相邻的边,若新边不形成环,就更新树,并将新边加入优先队列。 - Kruskal算法: - 先将所有的边按照权重升序排序。 - 创建一个空的最小生成树,然后依次取出排序后的边,如果这条边连接的两个顶点不在同一个连通分量,则将其添加到树中。 如果你需要更详细的代码示例,或者有具体的问题想了解(比如如何处理环、如何实现优先队列等),请告诉我,我会为你提供相应的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值