客观题
- 用链表(llink-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n-1个空指针。 False n个结点有n-1条边,每条边使用一个指针,故有2n-(n-1),即n+1个空指针
-
任何二叉搜索树中同一层的结点从左到右是有序的(从小到大)。 Ture 注意区分二叉搜索树和堆的定义即可
-
在一棵二叉搜索树上查找63,序列39、101、25、80、70、59、63是一种可能的查找时的结点值比较序列。
False 二叉搜索树,非空左子树的所有键值小于其根结点的键值。 非空右子树的所有键值大于其根结点的键值。||所以25不可能出现
- 中根遍历二叉查找树所得序列一定是有序序列。
False - 二叉搜索树T的最小元素有可能不位于树根的左子树。
True
-
含有25个结点的二叉排序树上,查找关键字为35的结点,则依次比较的关键字序列有可能是( )。
A.28,36,18,46,35
B.18,36,28,46,35
C.46,28,18,36,35
D.46,36,18,28,35
选D 画图,并且满足二叉搜索树对键值大小的要求。A.46出错,B.46出错,C.36出错 -
对于下列关键字序列,不可能构成某二叉排序树中一条查找路径的序列是( )。
A.95,22,91,24,94,71
B.92,20,91,34,88,35
C.21,89,77,29,36,38
D.12,25,71,68,33,34
选A 判断方法同上,24出错
- 已知由(60,30,56,78,12,45)序列构成的二叉排序树,其等概率成功查找的平均查找长度为。
A.21/7
B.28/7
C.15/6
D.21/6
选C 先画出二叉树(注意键值条件),然后平均查找次数计算(本题为例):1+22+32+41=15*
-
Given a binary search tree with its postorder traversal sequence { 2, 7, 15, 10, 20, 19, 35, 21, 18 }. If 18 is deleted from the tree, which one of the following statements is FALSE?
A.One possible preprder traversal sequence of the resulting tree may be { 15, 10, 7, 2, 21, 19, 20, 35 }
B.One possible preprder traversal sequence of the resulting tree may be { 20, 10, 7, 2, 15, 21, 19, 35 }
C.One possible preprder traversal sequence of the resulting tree may be { 19, 10, 7, 2, 15, 21, 20, 35 }
D.It is possible that the resulting tree may have 3 leaves
选B 后序遍历,所以18是根结点,从后往前根据BST对键值的要求就能构造出二叉树,然后再根据删除方法来判断
- The time complexity of traversing a binary tree with N nodes and height H in levelorder (with the help of with an auxiliary queue) is __.
A.O(N)
B.O(H)
C.O(NlogH)
D.O(H+N)
选A - The space complexity of iteratively traversing a binary tree with N nodes and height H in inorder (with the help of an auxiliary stack) is __.
A.O(N)
B.O(H)
C.O(H+N)
D.O(NlogH)
选B
二叉搜索树的遍历,复杂度为O(H)
- 在二叉树结点的先序序列,中序序列和后序序列中,所有叶子结点的先后顺序( )。
A.都不相同
B.完全相同
C.先序和中序相同,而与后序不同
D.中序和后序相同,而与先序不同
选B
- The following binary tree is called an expression tree. Which one is the arithmetic expression that this tree represents?
A.A + B + C / ( D * E ) + ( F - G )
B.( A + B + C ) / ( D * E ) + ( F - G )
C.( A + B + C ) / ( D * E + ( F - G ) )
D.A + B + C / D * E + F - G
选C 中序遍历即可得到中缀表达式(先序后序对应前缀后缀),注意中缀表达式需要考虑优先级的问题(一个子树就有一个括号)
编程题
1. Height of BST
You are supposed to write a function of finding the height of a binary search tree with the given preorder sequence.
Format of function: int Height_of_BST( int preorder[], int N );
where the preorder sequence is stored in int preorder[], and the integer N is the number of nodes in the tree, which is guaranteed to be positive. The function Height_of_BST is supposed to return the height of the binary search tree.
Note:
It is guaranteed that the preorder sequence consists of distinct integers and does correspond to a binary search tree.
You may assume that MAXN is a small number (less than 100) in the judge’s program.
Sample program of judge:
#include <stdio.h>
#include <stdlib.h>
#define MAXN 10
int Height_of_BST( int preorder[], int N );
int main()
{
int preorder[MAXN], N, i;
scanf("%d", &N);
for (i=0; i<N; i++) scanf("%d", &preorder[i]);
printf("%d\n", Height_of_BST(preorder, N));
return 0;
}
/* Your function will be put here */
Sample Input:
9
10 6 2 9 8 25 20 22 30
Sample Output:
3
AC代码:
int Height_of_BST( int preorder[], int N ){
if(N!=0){
int i,a,b;
for(i=0; i<N; i++){
if(preorder[i] > preorder[0]) break;
}/*根据先序遍历数组定位左右子树,p[0]为根结点,小于的构成左子树,大于的构成右子树*/
/*次数,指针停留在构成右子树的第一个元素*/
a = Height_of_BST(preorder+1, i-1);//从p[1]开始的i-1个元素为左子树
b = Height_of_BST(preorder+i, N-i);//从p[i]开始的N-i个元素为右子树
if(a > b) return a+1;
else return b+1;/*取左右子树较大的一个,结果+1(根结点高度为1)*/
}
return -1;
}
2. 判断两棵二叉树是否同构(递归法)
判断两棵二叉树是否同构(递归法)
函数接口定义:bool Isomorphism(BiTree T1,BiTree T2);
裁判测试程序样例:
#include<iostream>
#include<string.h>
#define N 100;
using namespace std;
typedef struct BiNode{
char data;
struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char a[],int &i){
char ch;
ch=a[i++];
if(ch=='#') T=NULL;
else{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild,a,i);
CreateBiTree(T->rchild,a,i);
}
}
bool Isomorphism(BiTree T1,BiTree T2);
int main(){
BiTree T1,T2;
int i=0,j=0;
char a[N];
char b[N];
cin>>a>>b;
CreateBiTree(T1,a,i);
CreateBiTree(T2,b,j);
cout<<Isomorphism(T1,T2);
return 0;
}
/* 请在这里填写答案 */
输入样例:
输入两行字符序列先序递归构建两棵二叉树。每个字符对应一个树节点,#表示空节点。
ABD#E###CF##G##
HIJ#K###LM##N##
输出样例:
同构输入1,否则输入0。
1
AC代码
bool Isomorphism(BiTree T1,BiTree T2){
if(!T1 && !T2) return true;//两者都为空,同构
if((!T1 && T2)|| (!T2 &&T1)) return false;//一空一非空,异构
//若左子树同构,右子树也同构,返回true
if(Isomorphism(T1->lchild,T2->lchild)&&Isomorphism(T1->rchild,T2->rchild))
return true;
}
3.求根结点到x结点的路径(递归法)
求根结点到x结点的路径(假定结点值不重复)。
函数接口定义:
bool Findxpath(BiTree bt,char x,vector<char> tmppath,vector<char> &path);
裁判测试程序样例:
#include<iostream>
#include<stdlib.h>
#include<vector>
using namespace std;
typedef struct BiNode{
char data;
struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T){
char ch;
cin>>ch;
if(ch=='#') T=NULL;
else{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
bool Findxpath(BiTree bt,char x,vector<char> tmppath,vector<char> &path);
int main(){
BiTree T;
char x;
vector<char>tmppath;
vector<char>path;
CreateBiTree(T);
cin>>x;
Findxpath(T,x,tmppath,path);
for(int i=0;i<path.size();i++)
cout<<path[i]<<" ";
return 0;
}
/* 请在这里填写答案 */
输入样例:
输入一行字符序列先序递归构建二叉树。每个字符对应一个结点,#表示空结点。第二行输入一个结点值x。
52#3##41##6##
3
输出样例:
输出从根到结点x的路径。
5 2 3
AC代码:
bool Findxpath(BiTree bt,char x,vector<char> tmppath,vector<char> &path){
if (!bt) return false;//当树为空时,返回false
tmppath.push_back(bt->data);//否则,暂存结点
if (bt->data==x){//若根结点等于x,则返回。
path=tmppath;
return true;
}//若在左子树或右子树找到x,则返回
if (Findxpath(bt->lchild,x,tmppath,path)||Findxpath(bt->rchild,x,tmppath,path))
return true;
else
return false;
}
4.二叉搜索树的操作集
本题要求实现给定二叉搜索树的5种常用操作。
函数接口定义:
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
其中BinTree结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
函数Insert将X插入二叉搜索树BST并返回结果树的根结点指针;
函数Delete将X从二叉搜索树BST中删除,并返回结果树的根结点指针;如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
函数FindMin返回二叉搜索树BST中最小元结点的指针;
函数FindMax返回二叉搜索树BST中最大元结点的指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
void InorderTraversal( BinTree BT ); /* 中序遍历,由裁判实现,细节不表 */
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
int main()
{
BinTree BST, MinP, MaxP, Tmp;
ElementType X;
int N, i;
BST = NULL;
scanf("%d", &N);
for ( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Insert(BST, X);
}
printf("Preorder:"); PreorderTraversal(BST); printf("\n");
MinP = FindMin(BST);
MaxP = FindMax(BST);
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
Tmp = Find(BST, X);
if (Tmp == NULL) printf("%d is not found\n", X);
else {
printf("%d is found\n", Tmp->Data);
if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
}
}
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Delete(BST, X);
}
printf("Inorder:"); InorderTraversal(BST); printf("\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3
输出样例:
Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9
AC代码
BinTree Insert( BinTree BST, ElementType X )
{
if(!BST){
BST=(BinTree)malloc(sizeof(struct TNode));
BST->Data=X;
BST->Left=BST->Right=NULL;
} else{
if(X<BST->Data)
BST->Left=Insert(BST->Left,X);
else if(X>BST->Data)
BST->Right=Insert(BST->Right,X);
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X )
{
Position tmp;
if(!BST)
printf("%s","Not Found\n");
else{
if(X<BST->Data)
BST->Left=Delete(BST->Left,X);
else if(X>BST->Data)
BST->Right=Delete(BST->Right,X);
else{//BST就是要删除的结点
if(BST->Left&&BST->Right){
//从右子树中找到最小元素填充被删除结点
tmp=FindMin(BST->Right);
BST->Data=tmp->Data;
//从右子树中删除最小元素
BST->Right=Delete(BST->Right,BST->Data);
}
else{//被删除结点仅有一个子结点或无子结点
tmp=BST;
if(!BST->Left)//只有右孩子或子结点
BST=BST->Right;
else//只有左孩子
BST=BST->Left;
free(tmp);
}
}
}
return BST;
}
Position Find( BinTree BST, ElementType X )
{
BinTree t=BST,t1,t2;
if(t==NULL) return NULL;
if(t->Data==X)
return t;
else
{t1=Find(t->Left,X);
if(t1) return t1;
else{
t2= Find(t->Right,X);
if(t2) return t2;
else return NULL;
}
}
}
Position FindMin( BinTree BST ){
BinTree t=BST;
if(t)
while(t->Left)
t=t->Left;
return t;
}
Position FindMax( BinTree BST ){
BinTree t=BST;
if(t)
while(t->Right)
t=t->Right;
return t;
}
5.The Kth Largest in BST
Given a binary search tree, you are supposed to find the node that contains the K-th largest key.
Format of function:BinTree KthLargest ( BinTree T, int K );
where BinTree is defined as the following:
typedef struct TNode *BinTree;
struct TNode{
int Key;
BinTree Left;
BinTree Right;
};
The function KthLargest is supposed to return the pointer that points to the node that contains the K-th largest key in the binary search tree T.
Here T is not empty and all its keys are distinct positive integers. K is positive and is never more than the total number of nodes in the tree.
Sample program of judge:
#include <stdio.h>
#include <stdlib.h>
typedef struct TNode *BinTree;
struct TNode{
int Key;
BinTree Left;
BinTree Right;
};
BinTree BuildTree(); /* details omitted */
BinTree KthLargest ( BinTree T, int K );
int main()
{
BinTree T, P;
int K;
T = BuildTree();
scanf("%d", &K);
P = KthLargest(T, K);
printf("%d\n", P->Key);
if (P->Left) printf("%d\n", P->Left->Key);
else printf("NULL\n");
if (P->Right) printf("%d\n", P->Right->Key);
else printf("NULL\n");
return 0;
}
/* Your function will be put here */
Sample Input: (for the following tree)
4
Sample Output:
5
NULL
7
AC代码:
int count=0;//全局计数器
BinTree KthLargest ( BinTree T, int K ){
if(!T) return NULL;
else
{ //先在右子树找
BinTree* right=KthLargest(T->Right,K);
if(right) return right;
//若左子树未找到,再考察根结点
count++;
if(count==K) return T;
//若根结点不是,再在左子树找
BinTree left=KthLargest(T->Left,K);
if(left) return left;
}
}