经典二叉树OJ题

目录

1、判断二叉树是否是完全二叉树

2、单值二叉树

3、二叉树的前序遍历

4、相同的树

5、对称二叉树

6、另一颗树的子树

7、二叉树的遍历

8、翻转二叉树

9、平衡二叉树


1、判断二叉树是否是完全二叉树

思路:

层序遍历的思路(利用队列,一层带一层),

当遇到NULLbreak,再判断后面有没有非NULL的元素,

若有,则非完全二叉树,反之,是完全二叉树

bool BinaryTreeComplete(BTNode* root)// 判断二叉树是否是完全二叉树
{
	if (root == NULL)
		return false;
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
			break;
		QueuePush(&q, front->_left);
		QueuePush(&q, front->_right);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front != NULL)
		{
			QueueDestroy(&q);//防止内存泄漏
			return false;
		}
	}

	return true;
}

2、单值二叉树

965. 单值二叉树 - 力扣(LeetCode)

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树,

只有给定的树是单值二叉树时,才返回 true;否则返回 false

示例:

输入:[1,1,1,1,1,null,1]
输出:true

思路1:传值

为NULL return true,因为NULL没有关系

不为k(相同的值),直接 return false,不用再向下遍历了

为k,再向下遍历,没有找到不相同的k,就 return true

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

bool _isUnivalTree(struct TreeNode* root,int k)
{
    if(root == NULL)
    return true;
    if(root->val != k)
    return false;
    return _isUnivalTree(root->left,k)&&_isUnivalTree(root->right,k);
}

bool isUnivalTree(struct TreeNode* root) {
    int k = root->val;
    return _isUnivalTree(root,k);
}

思路2:不传值

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool isUnivalTree(struct TreeNode* root) {
    if(root == NULL)
    return true;
    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);
}

3、二叉树的前序遍历

144. 二叉树的前序遍历 - 力扣(LeetCode)

给你二叉树的根节点 root ,返回它节点值的 前序 遍历

示例:

输入:root = [1,null,2,3]

输出:[1,2,3]

思路:

C语言返回数组时,要返回数组的大小,但函数只能返回一个值,于是用了指针(作为输出型参数,如果这个参数是用来做输入的,就叫输入型参数;如果这个参数的目的是用来做输出的,就叫输出型参数)

先递归算出树的大小

为什么用pi,直接用  *arr = root->val;  arr++; 不行吗?

因为    _preorderTraversal(root->left,arr);
           _preorderTraversal(root->right,arr);

 return 回来时_preorderTraversal(root->right,arr);中的 arr 并没有改变

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

int treeSize(struct TreeNode* root)
{
    return root == NULL?0:treeSize(root->left)+treeSize(root->right)+1;
}

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

int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize = treeSize(root);
    int* arr = (int*)malloc(sizeof(int)*(*returnSize));
    int i = 0;
    _preorderTraversal(root,arr,&i);
    return arr;
}

4、相同的树

100. 相同的树 - 力扣(LeetCode)

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同,

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的

示例:

输入:p = [1,2,3], q = [1,2,3]
输出:true

思路:

当都为NULL时,return true;

有一个为NULL,return false;

值不相等,return false;

再左右子树相互比较

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
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、对称二叉树

101. 对称二叉树 - 力扣(LeetCode)

给你一个二叉树的根节点 root , 检查它是否轴对称

示例:

输入:root = [1,2,2,3,4,4,3]
输出:true

思路:

利用isSameTree():,注意是轴对称,所以

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

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

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

6、另一颗树的子树

572. 另一棵树的子树 - 力扣(LeetCode)

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 

示例:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

思路:

root为NULL,return false;

先判断root->val == subRoot->val; ,再利用isSameTree(root,subRoot); 成立 return true; 就找到了

反之,在从左右子树找,只要找到就行,所以用||

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

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

7、二叉树的遍历

二叉树遍历_牛客题霸_牛客网

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储),再对二叉树进行中序遍历输出遍历结果

示例:

输入:

abc##de#g##f###

输出:

c b e g d f a 

思路:

就算为'#'return NULL前  也要更新下标

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef  struct TreeNode {
    int val;
    struct TreeNode* left;
    struct TreeNode* right;

} TreeNode;

TreeNode* creeatTree(char* arr,int* pi) {
    if(arr[*pi] == '#')
    {
        (*pi)++;
        return NULL;
    }
    TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
    assert(root);
    root->val = arr[(*pi)++];
    root->left = creeatTree(arr,pi);
    root->right = creeatTree(arr,pi);
    return root;
}

void binaryTreeInOrder(TreeNode* root)
{
    if(root == NULL)
    return;
    binaryTreeInOrder(root->left);
    printf("%c ",root->val);
    binaryTreeInOrder(root->right);
}

int main() {
    char arr[100];
    scanf("%s", arr);
    int i = 0;
    TreeNode* root = creeatTree(arr,&i);
    binaryTreeInOrder(root);
    return 0;
}

8、翻转二叉树

226. 翻转二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

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

9、平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode)

思路:

利用之前的算高度的思想,这时返回类型是int,所以要新建一个子函数,

当发现左右子树高度差>1,这时就已经确定结果了,可我现在的阶段不知道怎么立即结束递归并返回,

所以就用了输出型参数int* px记录 存在左右子树高度差>1,然后在原函数里再判断

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int _isBalanced(struct TreeNode* root,int* px)
{
    if(root == NULL)
    return 0;
    int leftheight = _isBalanced(root->left,px);
    int rightheight = _isBalanced(root->right,px);
    int flag = leftheight>rightheight?leftheight-rightheight:rightheight-leftheight;
    if(flag > 1)
    *px = 0;
    return leftheight>rightheight?leftheight+1:rightheight+1;

}

bool isBalanced(struct TreeNode* root) {
    int x = 1;
    _isBalanced(root,&x);
    return x == 1?true:false;
}

总结:二叉树的遍历数组扯上关系时,一般要传下标的地址保持下标的更新 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lzc_217

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值