文章目录
- 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