C语言数据结构-----二叉树(3)二叉树相关练习题

前言

前面详细讲述了二叉树的相关知识,为了巩固,做一些相关的练习题

文章目录

  • 前言
  • [1.某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为?](#1.某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为?)
  • 2.下列数据结构中,不适合采用顺序存储结构的是?
  • [3.在具有 2n 个结点的完全二叉树中,叶子结点个数为?](#3.在具有 2n 个结点的完全二叉树中,叶子结点个数为?)
  • 4.一棵完全二叉树的节点数位为531个,那么这棵树的高度为?
  • 5.一个具有767个节点的完全二叉树,其叶子节点个数为?
  • 6.单值二叉树
  • 7.相同的树
  • 8.对称二叉树
  • 9.二叉树的最大深度
  • 10.另一棵树的子树
  • 11.翻转二叉树
  • 12.二叉树的前序遍历
    • [12.1 二叉树的中序遍历](#12.1 二叉树的中序遍历)
    • [12.2 二叉树的后序遍历](#12.2 二叉树的后序遍历)
  • 13.平衡二叉树
  • [14.在一颗度为3的树中,度为3的结点有2个,度为2的结点有1个,度为1的结点有2个,则叶子结点有( )个](#14.在一颗度为3的树中,度为3的结点有2个,度为2的结点有1个,度为1的结点有2个,则叶子结点有( )个)
  • [15.设根结点的深度为1,则一个拥有n个结点的二叉树的深度一定在( )区间内](#15.设根结点的深度为1,则一个拥有n个结点的二叉树的深度一定在( )区间内)
  • [16.一颗完全二叉树有1001个结点,其叶子结点的个数是( )](#16.一颗完全二叉树有1001个结点,其叶子结点的个数是( ))
  • [17.一颗拥有1000个结点的树度为4,则它的最小深度是( )](#17.一颗拥有1000个结点的树度为4,则它的最小深度是( ))
  • [18.如果一颗二叉树的前序遍历的结果是ABCD,则满足条件的不同的二叉树有( )种](#18.如果一颗二叉树的前序遍历的结果是ABCD,则满足条件的不同的二叉树有( )种)
  • [19.已知某二叉树的前序遍历序列为5 7 4 9 6 2 1,中序遍历序列为4 7 5 6 9 1 2,则其后序遍历序列为( )](#19.已知某二叉树的前序遍历序列为5 7 4 9 6 2 1,中序遍历序列为4 7 5 6 9 1 2,则其后序遍历序列为( ))
  • [20.已知某二叉树的中序遍历序列为JGDHKBAELIMCF,后序遍历序列为JGKHDBLMIEFCA,则其前序遍历序列为( )](#20.已知某二叉树的中序遍历序列为JGDHKBAELIMCF,后序遍历序列为JGKHDBLMIEFCA,则其前序遍历序列为( ))
  • [21.已知某二叉树的前序遍历序列为ABDEC,中序遍历序列为BDEAC,则该二叉树( )](#21.已知某二叉树的前序遍历序列为ABDEC,中序遍历序列为BDEAC,则该二叉树( ))

在做题之前,需要补充二叉树的一条性质:对任何一棵二叉树, 如果度为0其叶结点个数为n~0~ , 度为2的分支结点个数为n~2~ ,则有:

n~0~=n~2~ +1

1.某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为?

A 不存在这样的二叉树

B 200

C 198

D 199

解析:B

叶子节点即为度为0的节点,由性质可知,叶子结点数=199+1=200

2.下列数据结构中,不适合采用顺序存储结构的是?

A 非完全二叉树

B 堆

C 队列

D 栈

解析:A

3.在具有 2n 个结点的完全二叉树中,叶子结点个数为?

A n

B n+1

C n-1

D n/2

解析:A

4.一棵完全二叉树的节点数位为531个,那么这棵树的高度为?

A 11

B 10

C 8

D 12

解析:B

5.一个具有767个节点的完全二叉树,其叶子节点个数为?

A 383

B 384

C 385

D 386

解析:B

6.单值二叉树

c 复制代码
bool isUnivalTree(struct TreeNode* root) 
{
    if (root==NULL)
    return true;
    if (root->left!=NULL&&root->left->val!=root->val)
    return false;
    if (root->right!=NULL&&root->right->val!=root->val)
    return false;
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

解析:

如果树为空,那么并不违反规则。

如果树的左边不为空,并且左边的值不等于root的值那么错误。右边同理。

最后对左子树和右子树递归调用!

7.相同的树

c 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) 
{
    if (p==NULL&&q==NULL)
    return true;
    if (p==NULL&&q!=NULL)
    return false;
    if (q==NULL&&p!=NULL)
    return false;
    if (p->val!=q->val)
    return false;

    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

解析:先把几种特殊情况写了,就是pq都为空,p空q不空,q空p不空,pq都不空但值不相等。

写完了几种特殊情况就可以递归左子树和右子树判断了!

8.对称二叉树

c 复制代码
bool doubleisSymmetric(struct TreeNode* root1,struct TreeNode* root2) 
{
    if (root1==NULL&&root2==NULL)
    return true;
    if (root1==NULL||root2==NULL)
    return false;
    if (root1->val!=root2->val)
    return false;

    return doubleisSymmetric(root1->left,root2->right)&&doubleisSymmetric(root1->right,root2->left);
}

bool isSymmetric(struct TreeNode* root)
{
    return doubleisSymmetric(root->left,root->right);
}

解析

9.二叉树的最大深度

c 复制代码
int maxDepth(struct TreeNode* root)
{
    return (root==NULL)?0:fmax(maxDepth(root->left),maxDepth(root->right))+1;
}

解析:

用一个三目就可以解决,如果为空深度就为0,否则的话遍历左子树和右子树遍历一次+1,一直到底,左边和右边谁打谁就是深度。

10.另一棵树的子树

c 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) 
{
    if (p==NULL&&q==NULL)
    return true;
    if (p==NULL||q==NULL)
    return false;
    if (p->val!=q->val)
    return false;

    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
    if(root==NULL)
    return false;
    
    if (root->val==subRoot->val)
    {
        if (isSameTree(root,subRoot))
        return true;
    }

    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

11.翻转二叉树

第一次写是这样的,但是发现这样写麻烦了,没必要直接写个swap函数,还调用二级指针麻烦!

c 复制代码
void swap(struct TreeNode** a, struct TreeNode** b) {
    struct TreeNode* temp = *a;
    *a = *b;
    *b = temp;
}

struct TreeNode* invertTree(struct TreeNode* root) {
    if (root == NULL)
        return NULL;
    
    swap(&(root->left), &(root->right));
    
    invertTree(root->left);
    invertTree(root->right);
    
    return root;
}

修改一下,看着简单舒服多了

c 复制代码
struct TreeNode* invertTree(struct TreeNode* root) 
{
        if (root == NULL) 
        return NULL;
         struct TreeNode* temp;
        temp=root->left;
        root->left=root->right;
        root->right=temp;
        invertTree(root->left);
        invertTree(root->right);
        return root;
}

到这里,这个级别的代码就应该不需要解析了吧,都能看懂。

12.二叉树的前序遍历

c 复制代码
void preorder(struct TreeNode* root, int* res, int* resSize) 
{
    //root:当前节点的指针。
    //res:存储遍历结果的数组。
    //resSize:指向遍历结果数组元素个数的指针。
    if (root == NULL) 
        return;
    res[(*resSize)++] = root->val;
    preorder(root->left, res, resSize);
    preorder(root->right, res, resSize);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    int* res = malloc(sizeof(int) * 2000);
    *returnSize = 0;
    preorder(root, res, returnSize);
    return res;
}

12.1 二叉树的中序遍历

c 复制代码
void inorder(struct TreeNode* root, int* res, int* resSize) 
{
    //root:当前节点的指针。
    //res:存储遍历结果的数组。
    //resSize:指向遍历结果数组元素个数的指针。
    if (root == NULL) 
        return;
    inorder(root->left, res, resSize);
      res[(*resSize)++] = root->val;
    inorder(root->right, res, resSize);
}

int* inorderTraversal(struct TreeNode* root, int* returnSize) 
{
    int* res = malloc(sizeof(int) * 2000);
    *returnSize = 0;
    inorder(root, res, returnSize);
    return res;
}

12.2 二叉树的后序遍历

c 复制代码
void postorder(struct TreeNode* root, int* res, int* resSize) 
{
    //root:当前节点的指针。
    //res:存储遍历结果的数组。
    //resSize:指向遍历结果数组元素个数的指针。
    if (root == NULL) 
        return;
    postorder(root->left, res, resSize);
    postorder(root->right, res, resSize);
    res[(*resSize)++] = root->val;
}

int* postorderTraversal(struct TreeNo
de* root, int* returnSize) 
{
     int* res = malloc(sizeof(int) * 2000);
    *returnSize = 0;
    postorder(root, res, returnSize);
    return res;
}

这三道题如出一辙,所以我把他们放到一起。代码都很简单,大家应该都能看懂!

13.平衡二叉树

c 复制代码
int TreeHeight(struct TreeNode* root)
{
	if (root == NULL)
		return 0;
	int leftHeight = TreeHeight(root->left);
	int rightHeight = TreeHeight(root->right);

	return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}


bool isBalanced(struct TreeNode* root) 
{
    	if (root == NULL)
		return true;
        else 
        return fabs(TreeHeight(root->left) - TreeHeight(root->right)) <= 1 
        && isBalanced(root->left) 
        && isBalanced(root->right);
}

解析:

先求二叉树的左高度和右高度,然后递归返回来判断是否满足题意。

14.在一颗度为3的树中,度为3的结点有2个,度为2的结点有1个,度为1的结点有2个,则叶子结点有( )个

A.4

B.5

C.6

D.7

解析:C

15.设根结点的深度为1,则一个拥有n个结点的二叉树的深度一定在( )区间内

A.[log(n + 1),n]

B.[logn,n]

C.[log(n + 1),n - 1]

D.[log(n + 1),n + 1]

解析:

最大深度: 即每次只有一个节点,次数二叉树的高度为n,为最高的高度

最小深度: 此树为完全二叉树, 如果是完全二叉树

根据二叉树性质,完全二叉树的高低为 h = log(n+1)向上取整

故答案为 [log(n + 1),n]

16.一颗完全二叉树有1001个结点,其叶子结点的个数是( )

A.251

B.500

C.501

D.不能确定

解析:C

完全二叉树的最后一个结点的编号一定是1001,则它的父结点的编号为1001/2=500,则叶子结点个数为1001-500=501.

总结一下:完全二叉树的最后一个结点的编号是n,则它的父结点的编号为[n/2],则叶子结点个数为n-[n/2]。

17.一颗拥有1000个结点的树度为4,则它的最小深度是( )

A.5

B.6

C.7

D.8

解析:B

如果这棵树每一层都是满的,则它的深度最小,假设它为一个四叉树,高度为h,则这个数的节点个数为(4^h - 1) / 3,当h = 5, 最大节点数为341, 当h = 6, 最大节点数为1365,所以最小深度应该为6。

18.如果一颗二叉树的前序遍历的结果是ABCD,则满足条件的不同的二叉树有( )种

A.13

B.14

C.15

D.16

解析:B

19.已知某二叉树的前序遍历序列为5 7 4 9 6 2 1,中序遍历序列为4 7 5 6 9 1 2,则其后序遍历序列为( )

A.4 2 5 7 6 9 1

B.4 2 7 5 6 9 1

C.4 7 6 1 2 9 5

D.4 7 2 9 5 6 1

解析:C

20.已知某二叉树的中序遍历序列为JGDHKBAELIMCF,后序遍历序列为JGKHDBLMIEFCA,则其前序遍历序列为( )

A.ABDGHJKCEFILM

B.ABDGJHKCEILMF

C.ABDHKGJCEILMF

D.ABDGJHKCEIMLF

解析:B

21.已知某二叉树的前序遍历序列为ABDEC,中序遍历序列为BDEAC,则该二叉树( )

A.是满二叉树

B.是完全二叉树,不是满二叉树

C.不是完全二叉树

D.是所有的结点都没有右子树的二叉树

解析:C

相关推荐
月下绯烟3 分钟前
chapter14 数据结构与集合源码 知识点总结Note
java·数据结构·算法
復禮4 分钟前
树和二叉树的概念以及结构
数据结构·算法
Tisfy5 分钟前
LeetCode 2414.最长的字母序连续子字符串的长度:一次遍历
算法·leetcode·字符串·题解·遍历
Smoke filled ゞ away5 分钟前
数据结构之存储位置
java·数据结构·算法
☆璇6 分钟前
【数据结构】顺序表和链表经典题目
c语言·数据结构·链表
¥ 多多¥7 分钟前
数据结构:单链表实现信息管理
c语言·数据结构·算法
@小了白了兔7 分钟前
数据结构——二叉搜索树、Map和Set
数据结构·算法
进击的_鹏7 分钟前
数据结构之算法复杂度
数据结构·算法
幸苦的马侬8 分钟前
数据结构-图
数据结构·算法
荣世蓥8 分钟前
4.C_数据结构_队列
数据结构