概念
二叉排序树是一颗特殊的二叉树,它是一颗二叉树但同时满足如下条件:对于树上的任意一个结点,其上的数值必大于等于其左子树上任意结点数值,必小于等于其右子树上任意结点的数值。
由于各个数字插入的顺序不同,所得到的二叉排序树的形态也很可能不同,所以不同的插入顺序对二叉排序树的形态有重要的影响,但其都有一个共同点:若对二叉排序树进行中序遍历,那么其遍历结果必然是一个递增序列,所以通过建立二叉排序树就能对原无需序列进行排序,并实现动态维护。
例3.5 二叉排序树 (1201)
题目描述:输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历。
输入:输入第一行包括一个整数n(1<=n<=100)。 接下来的一行包括n个整数。
输出:可能有多组测试数据,对于每组数据,将题目所给数据建立一个二叉排序树,并对二叉排序树进行前序、中序和后序遍历。每种遍历结果输出一行。每行最后一个数据之后有一个空格。
样例输入: 5 1 6 5 9 8 样例输出: 1 6 5 9 8 1 5 6 8 9 5 8 9 6 1
#include<stdio.h> #include<string.h> using namespace std; struct Node{ Node *lchild; Node *rchild; int x; }Tree[110]; int loc; Node *create(){ Tree[loc].lchild=Tree[loc].rchild=NULL; return &Tree[loc++]; } void preOrder(Node *T){ printf("%d ",T->x); if(T->lchild) preOrder(T->lchild); if(T->rchild) preOrder(T->rchild); } void postOrder(Node *T){ if(T->lchild) postOrder(T->lchild); if(T->rchild) postOrder(T->rchild); printf("%d ",T->x); } void inOrder(Node *T){ if(T->lchild) inOrder(T->lchild); printf("%d ",T->x); if(T->rchild) inOrder(T->rchild); } Node *insert(Node *T,int y){ if(T==NULL){ T=create(); T->x=y; return T; } else if(y>T->x) T->rchild=insert(T->rchild,y); else T->lchild=insert(T->lchild,y); return T; } int main(){ int n; while(scanf("%d",&n)!=EOF){ Node *T=NULL; loc=0; while(n--){ int t; scanf("%d",&t); T=insert(T,t); } preOrder(T); printf(" "); inOrder(T); printf(" "); postOrder(T); printf(" "); } return 0; }
例3.6 二叉搜索树 (1009)
- 题目描述:判断两序列是否为同一二叉搜索树序列
- 输入:开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
-
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
- 输出:如果序列相同则输出YES,否则输出NO
样例输入: 2 567432 543267 576342 0 样例输出: YES NO
解法一是作者写的比较直观的解法,通过四个char型数组来保存第一次和后面遍历的二叉树的中序排列和前序排列,通过strcmp来比较字符串即可判断两序列是否为同一二叉搜索树。
#include<stdio.h> #include<string.h> using namespace std; struct Node{ Node *lchild; Node *rchild; char x; }Tree[12]; int loc; Node *create(){ Tree[loc].lchild=Tree[loc].rchild=NULL; return &Tree[loc++]; } char s1[12];//第一个字符串中序 char s2[12];//第一个字符串前序 char s3[12];//比较字符串中序 char s4[12];//比较字符串前序 int index; void inOrder(Node *T,char *s){ if(T->lchild) inOrder(T->lchild,s); s[index++]=T->x; if(T->rchild) inOrder(T->rchild,s); } void preOrder(Node *T,char *s){ s[index++]=T->x; if(T->lchild) preOrder(T->lchild,s); if(T->rchild) preOrder(T->rchild,s); } Node *insert(Node *T,char y){ if(T==NULL){ Node *TT=create(); TT->x=y; return TT; } else if(y>T->x){ T->rchild=insert(T->rchild,y); } else T->lchild=insert(T->lchild,y); return T; } int main(){ int n; while(scanf("%d",&n)!=EOF){ if(n==0) break; char s[12]; scanf("%s",s); int L=strlen(s); loc=0; Node *T=NULL; for(int i=0;i<L;i++){ T=insert(T,s[i]); } index=0; inOrder(T,s1); index=0; preOrder(T,s2); for(int i=0;i<n;i++){ char ss[12]; scanf("%s",ss); loc=0; Node *TN=NULL; for(int i=0;i<L;i++) TN=insert(TN,ss[i]); index=0; inOrder(TN,s3); index=0; preOrder(TN,s4); if(strncmp(s1,s3,L)==0&&strncmp(s2,s4,L)==0)//strncmp指定长度比较,stricmp忽略大小写来比较 //if(strncmp(s1,&s2[3],3)==0) 就是比较s1和s2的第3个字符开始的内容 printf("YES "); else printf("NO "); } } return 0; }
解法二为书本实例代码如下:
#include<stdio.h> #include<string.h> using namespace std; struct Node{ Node *lchild; Node *rchild; int c; }Tree[110]; int loc; Node *create(){ Tree[loc].lchild=Tree[loc].rchild=NULL; return &Tree[loc++]; } char str1[25],str2[25];//保存二叉查找树的遍历结果,前序和中序连接得到字符串 int size1,size2;//保存在字符数组中的遍历得到字符个数 char *str;//当前正在保存字符串 int *size;//当前正在保存字符串中字符个数 void postOrder(Node *T){ if(T->lchild) postOrder(T->lchild); if(T->rchild) postOrder(T->rchild); str[(*size)++]=T->c+'0'; } void inOrder(Node *T){ if(T->lchild) inOrder(T->lchild); if(T->rchild) inOrder(T->rchild); str[(*size)++]=T->c+'0';//将结点中的字符放入正在保存的字符串中 } Node *Insert(Node *T,int 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; } int main(){ int n; char tmp[12]; while(scanf("%d",&n)!=EOF&&n!=0){ loc=0; Node *T=NULL; scanf("%s",tmp); for(int i=0;tmp[i]!=0;i++){ T=Insert(T,tmp[i]-'0'); } size1=0; str=str1;//将正在保存字符串设定为第一个字符串 size=&size1;//将正在保存字符串中的字符个数指针指向size1 postOrder(T); inOrder(T); str1[size1]=0; while(n--){ scanf("%s",tmp); Node *T2=NULL; for(int i=0;tmp[i]!=0;i++){ T2=Insert(T2,tmp[i]-'0'); } size2=0; str=str2; size=&size2; postOrder(T2); inOrder(T2); str[size2]=0; puts(strcmp(str1,str2)==0?"YES":"NO"); } } return 0; }