【数据结构】二叉树经典算法题和选择题

文章目录

  • 5.⼆叉树算法题
    • [5.1 单值⼆叉树](#5.1 单值⼆叉树)
    • [5.2 相同的树](#5.2 相同的树)
    • 5.3对称⼆叉树
    • [5.4 另⼀棵树的⼦树](#5.4 另⼀棵树的⼦树)
    • [5.5 ⼆叉树遍历](#5.5 ⼆叉树遍历)
      • [5.5.1 前序遍历](#5.5.1 前序遍历)
      • [5.5.2 中序遍历](#5.5.2 中序遍历)
      • [5.5.3 后序遍历](#5.5.3 后序遍历)
    • [5.6 ⼆叉树的构建及遍历](#5.6 ⼆叉树的构建及遍历)
  • 6.⼆叉树选择题

二叉树相关知识(点击跳转)

5.⼆叉树算法题

5.1 单值⼆叉树

题目链接(点击跳转)

思路:递归比较左右孩子结点值是否一样,如果结点为空返回true

c 复制代码
bool isUnivalTree(struct TreeNode* root)
{
    if(root==NULL)
        return true;
    //root非空,root跟左右孩子结点的值比较
    if(root->left&&root->left->val!=root->val)
        return false;
    if(root->right&&root->right->val!=root->val)
        return false;
    //左右孩子结点既不为空也与根结点的值相等,则判断根结点左右孩子结点是否为单值二叉树
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

5.2 相同的树

题目链接(点击跳转)

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);
}

5.3对称⼆叉树

题目链接(点击跳转)

思路:根结点为head,将根结点的左右子树分别当作p和q,比较p的左子树和q的右子树的值

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->right)&&isSameTree(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root)
{
   //将根结点的左子树和右子树传过去 
    return isSameTree(root->left,root->right);
}

5.4 另⼀棵树的⼦树

题目链接(点击跳转)

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;
    is(isSameTree(root,subRoot))
        return ture;
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);   
}

5.5 ⼆叉树遍历

5.5.1 前序遍历

题目链接(点击跳转)

c 复制代码
//求二叉树节点个数
int BinaryTreeSize(struct TreeNode* root)
{
    if(root==NULL)
        return 0;
    return 1+BinaryTreeSize(root->left)+BinaryTreeSize(root->right);
}
//前序遍历
void preOrder(struct TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
        return;
    arr[(*pi)++]=root->val;
    preOrder(root->left,arr,pi);
    preOrder(root->right,arr,pi);
}
int* preorderTraversal(struct TreeNode* root,int* returnSize)
{
    //*returnSize表示要返回的数组的大小
    //二叉树结点个数=*returnSize
    *returnSize=BinaryTreeSize(root);
    int* arr=(int*)malloc(sizeof(int)*(*returnSize));
    //前序遍历
    int i=0;
    preOrder(root,arr,&i);
    return arr;
}

5.5.2 中序遍历

题目链接(点击跳转)

c 复制代码
int BinaryTreeSize(struct TreeNode* root)
{
    if(root==NULL)
        return 0;
    return 1+BinaryTreeSize(root->left)+BinaryTreeSize(root->right);
}
//中序遍历
void inOrder(struct TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
        return;
    inOrder(root->left,arr,pi);
    arr[(*pi)++]=root->val;
    inOrder(root->right,arr,pi);
}
int* inorderTraversal(struct TreeNode* root,int* returnSize)
{
    *returnSize=BinaryTreeSize(root);
    int* arr=(int*)malloc(sizeof(int*)*(*returnSize));
    int i=0;
    inOrder(root,arr,&i);
    return arr;
}

5.5.3 后序遍历

题目链接(点击跳转)

c 复制代码
int BinaryTreeSize(struct TreeNode* root)
{
	if (root == NULL)
		return 0;
	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

void postOrder(struct TreeNode* root, int* arr, int* pi)
{
	if (root == NULL)
		return;
	postOrder(root->left, arr, pi);
	postOrder(root->right, arr, pi);
	arr[(*pi)++] = root->val;
}

int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
	*returnSize = BinaryTreeSize(root);
	int* arr = (int*)malloc(sizeof(int*) * (*returnSize));
	int i = 0;
	postOrder(root, arr, &i);
	return arr;
}

5.6 ⼆叉树的构建及遍历

题目链接(点击跳转)

c 复制代码
 #include <stdio.h>
#include<stdlib.h>
typedef struct BinaryTreeNode
{
    char data;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
}BTNode;

BTNode* buyNode(char ch)
{
    BTNode* newnode=(BTNode*)malloc(sizeof(BTNode));
    if(newnode==NULL)
    {
        perror("malloc");
        exit(1);
    }
    newnode->data=ch;
    newnode->left=newnode->right=NULL;
    return newnode;
}

//构建二叉树
BTNode* createTree(char* arr,int* pi)
{
    if(arr[(*pi)]=='#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode* root=buyNode(arr[(*pi)++]);
    root->left=createTree(arr,pi);
    root->right=createTree(arr,pi);
    return root;
}
//中序遍历
void InOrder(BTNode* root)
{
    if(root==NULL)
    {
        return;
    }
    InOrder(root->left);
    printf("%c ",root->data);
    InOrder(root->right);
}
int main() {
    //读取输入的字符串保存在数组中
    char arr[100];
    scanf("%s",arr);
    //根据先序遍历创建二叉树
    int i=0;
    BTNode* root=createTree(arr,&i);
    //中序遍历
    InOrder(root);
    return 0;
}

6.⼆叉树选择题

⼆叉树性质:对任何⼀棵⼆叉树,如果度为 0 其叶结点个数为n0,度为 2 的分⽀结点个数为 n2,则有n0 = n2 + 1

证明上述性质: 假设⼀个⼆叉树有 a 个度为2的节点, b 个度为1的节点, c 个叶节点(二叉树的结点只有三种情况:度为0,1,2),则这个⼆叉树的边数是 2a+b

另⼀⽅⾯,由于共有 a+b+c 个节点,所以边数等于 a+b+c-1(边数=结点个数-1)

结合上⾯两个公式: 2a+b = a+b+c-1 ,即: a = c-1

根据⼆叉树的性质,完成以下选择题:

1.某⼆叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该⼆叉树中的叶⼦结点数为( )

A 不存在这样的⼆叉树 B 200 C 198 D 199

答案是B
2.在具有 2n 个结点的完全⼆叉树中,叶⼦结点个数为( )

A n B n+1 C n-1 D n/2

n0=2n-n1-n2

2n0=2n-n1+1

在完全二叉树中,只可能出现0个或1个度为1的结点

2n0=2n+1或者2n0=2n,即n0=n+1/2(舍去)或者n0=n,选A
3.⼀棵完全⼆叉树的结点数位为531个,那么这棵树的⾼度为( )

A 11 B 10 C 8 D 12

对于满⼆叉树,层数为 K ,那么它的结点总数是2k-1,且第K层的结点个数为2k-1,所以第9层总的结点个数为29-1=511,第10层总的结点个数210-1=1023。所以这道题的二叉树前9层是满的,第10层没满

答案为B
4.⼀个具有767个结点的完全⼆叉树,其叶⼦结点个数为()

A 383 B 384 C 385 D 386

n0+n1+n2=767 n0=n2+1

2n0=768-n1,而n1只可能为0或1

n0=384或者383.5(舍去)

答案为B

链式⼆叉树遍历选择题

5.某完全⼆叉树按层次输出(同⼀层从左到右)的序列为 ABCDEFGH 。该完全⼆叉树的前序序列为( )

A ABDHECFG B ABCDEFGH C HDBEAFCG D HDEBFGCA

先还原二叉树,再根据"根左右",选A
6.⼆叉树的先序遍历和中序遍历如下:前序遍历:EFHIGJK;中序遍历:HFIEJKG.则⼆叉树根结点为 ()

A E B F C G D H

前序遍历先打印根结点,选A
7.设⼀课⼆叉树的中序遍历序列:badce,后序遍历序列:bdeca,则⼆叉树前序遍历序列为

A adbce B decab C debac D abcde

后序遍历最后的结点是根结点,在中序遍历中,根结点左边是左子树,右边是右子树(只有b),在后序遍历中c在dec中排最后,所以c是右子树的根结点,再从中序遍历中看c,c的左边是左子树d,右边是右子树e,所以选D
8.某⼆叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF ,则按层次输出(同⼀层从左到右) 的序列为

A FEDCBA B CBAFED C DEFCBA D ABCDEF

做法与第7题一样

所以选A

相关推荐
jllllyuz2 小时前
MATLAB多目标优化:SQP算法实现
数据结构·算法·matlab
im_AMBER2 小时前
数据结构 14 【复习】二叉树中序遍历 | 线索二叉树 | 树、森林、二叉树的转换 | 层次遍历二叉树
数据结构·笔记·学习·算法
im_AMBER2 小时前
Leetcode 88 K 和数对的最大数目
数据结构·c++·笔记·学习·算法·leetcode
酸菜牛肉汤面2 小时前
12、数据库为什么使用B+树而不是B树
数据结构·数据库·b树
酸菜牛肉汤面2 小时前
11、B树和B+树的区别
数据结构·b树
hetao17338372 小时前
2025-12-25~26 hetao1733837的刷题记录
c++·笔记·算法
bbq粉刷匠3 小时前
Java二叉树基础提升
java·数据结构·算法
客梦3 小时前
数据结构--栈
数据结构·笔记
nju_spy3 小时前
12月力扣每日一题(划分dp + 单调栈 + 堆 + 会议安排)
算法·leetcode·二分查找·动态规划·滑动窗口·单调栈·最大堆