二叉查找树 hdu(3791 && 3999)
所谓二叉搜索树(BST),就是每一个节点x,它的左子树中所有的关键字的值都小于x的关键字的值,而它右子树中所有的关键字的值都大于x的关键字的值。
对于刚刚接触BST可以做做hdu 3791;
hdu 3791 解题:
可以用动态的创建指针,也可以用静态的数组,反正这个题的数据非常之小,用什么都无所谓了;
动态写法
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 100 struct node { int e; node *lson; node *rson; }; typedef node* BST; void insert(int e,BST& p)//动态创建节点 { if(p == NULL) { p=new node(); p->e=e; p->lson = p->rson = NULL; return ; } if(p->e > e) insert(e, p->lson); else insert(e, p->rson); } void Delete(BST p) { if(p == NULL) return ; Delete(p->lson); Delete(p->rson); delete(p); } int flag; void comp(BST p1,BST p2)//比较两棵树是不是一样的,只有每个节点一样才是相同 { //如果节点不相同,就标记 if((p1 == NULL && p2 != NULL) || (p1 !=NULL && p2 ==NULL)) { flag=1; return ; } if(p1 == NULL) return ; if(p1 -> e != p2 ->e) { flag=1; return; } comp(p1->lson,p2->lson); comp(p1->rson,p2->rson); } int main() { int t,i; char c[maxn]; char cs[maxn]; while(scanf("%d",&t),t) { node * bst = NULL; scanf("%s",c); int len=strlen(c); for(i=0; i<len; i++) insert(c[i]-'0', bst); while(t--) { scanf("%s",cs); flag=0; BST bst1 = NULL; for(i=0; i<strlen(cs); i++) { insert(cs[i]-'0',bst1); } for(i=0; i<strlen(cs); i++) { comp(bst,bst1); } if(flag == 1) printf("NO\n"); else printf("YES\n"); Delete(bst1); } Delete(bst); } return 0; }
静态的就要多开很多没用的空间,最多有10个节点,最坏情况下可能树的高度有10层;所以数组最大要1<<10的大小;而访问节点i的左海子就用该节点 i<<1;如果访问右孩子则 i<<1 | 1;
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define inf 1<<30 #define maxn 1<<11 #define lson n<<1 #define rson n<<1 | 1 int bst1[maxn],bst2[maxn]; void insert(int n,int tt ,int bst[]) { if(bst[n] == inf) { bst[n] =tt; return ; } if(tt < bst[n]) insert(lson,tt,bst); else insert(rson,tt,bst); } void clear(int bst[]) { for(int i = 0; i < maxn; i++) { bst[i] = inf; } } int comp(int bst1[],int bst2[]) { for(int i=0;i<maxn;i++) { if(bst1[i] != bst2[i]) return 0; } return 1; } int main() { int t,i,tt,len; char st[11]; while(scanf("%d",&t),t) { clear(bst1); scanf("%s",st); len=strlen(st); bst1[1] = st[0] - '0'; for(i=1 ; i<len ; i++) { tt=st[i] - '0'; insert(1,tt,bst1); } while(t--) { clear(bst2); scanf("%s",st); len=strlen(st); bst2[1] = st[0] - '0'; for(i=1 ; i<len ; i++) { tt=st[i] - '0'; insert(1,tt,bst2); } if(comp(bst1,bst2)) printf("YES\n"); else printf("NO\n"); } } return 0; }
hdu 3999
题目描述了什么是BST,并要输出最小的可以变成这棵树的最小序列,其实质要建好了树,在一次先序遍历就可以了。这个节点比较多还是用动态的还些。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 100009 typedef struct node* BST; struct node { int e; BST lson; BST rson; }; int elem[maxn]; int n,count; void insert(int e,BST& p) { if(p == NULL) { p = new node(); p->e=e; p->lson = p->rson =NULL; return ; } if(p->e > e) insert(e,p->lson); else insert(e,p->rson); } void DFS(BST p) { if(p == NULL) return ; elem[count++]=p->e; DFS(p->lson); DFS(p->rson); } void Delete(BST p) { if(p == NULL) return ; Delete(p->lson); Delete(p->rson); delete(p); } int main() { int i; while(scanf("%d",&n)!=EOF) { BST bst = NULL; for(i=0;i<n;i++) { scanf("%d",&elem[i]); insert(elem[i],bst); } count = 0; DFS(bst); Delete(bst); printf("%d",elem[0]); for(i=1;i<n;i++) printf(" %d",elem[i]); printf("\n"); } return 0; } /* 4 1 3 4 2 */