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

文章目录

  • 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

相关推荐
ZPC82108 分钟前
【无标题】
人工智能·pytorch·算法·机器人
2301_7644413310 分钟前
使用python构建的STAR实验ΛΛ̄自旋关联完整仿真
开发语言·python·算法
Rainy Blue88314 分钟前
前缀和与差分(蓝桥杯高频考点)
数据结构·算法·蓝桥杯
Dfreedom.14 分钟前
机器学习经典算法全景解析与演进脉络(无监督学习篇)
人工智能·学习·算法·机器学习·无监督学习
421!20 分钟前
ESP32学习笔记之GPIO
开发语言·笔记·单片机·嵌入式硬件·学习·算法·fpga开发
夏日听雨眠24 分钟前
数据结构(单循环链表)
数据结构·链表
智算菩萨28 分钟前
【How Far Are We From AGI】4 AGI的“生理系统“——从算法架构到算力基座的工程革命
论文阅读·人工智能·深度学习·算法·ai·架构·agi
福赖30 分钟前
《算法:生产车间》
算法
空空潍39 分钟前
LeetCode力扣 hot100一刷完结
算法·leetcode
leaves falling42 分钟前
搜索插入位置(第一个≥target的位置)
算法