数据结构-二叉树-链式(二)-OJ

本文讲解了二叉树的查找、对称性检测、前序和层序遍历方法,以及基于字符串创建二叉树和子树判断。
摘要由CSDN通过智能技术生成

一、二叉树查找值为x的节点

这道题的坑就是我们不知道如何把接收到的返回值返回到最外面。

BTNode* BinaryTreeFind(BTNode* root, BTNodeDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->data == x)
	{
		return root;
	}
	//去找左子树
	BTNode* lefttemp  = BinaryTreeFind(root->left,x);
	if (lefttemp)
	{
		return lefttemp;
	}
	BTNode* righttemp = BinaryTreeFind(root->right,x);
	if (righttemp)
	{
		return righttemp;
	}

	return NULL;
}

递归展开图

相同的树

根比根,左子树比左子树,右子树比右子树

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 _isSymmetric(struct TreeNode* p,struct TreeNode* q);
bool isSymmetric(struct TreeNode* root) {
    if(root == NULL)
    {
        return false;
    }
    return _isSymmetric(root->left,root->right);
}

bool _isSymmetric(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 _isSymmetric(p->left,q->right)
    &&_isSymmetric(p->right,q->left);
}

二叉树的前序遍历

//可以看到需要返回数组的大小,所以我们可以求出二叉树的节点个数,用来开辟数组
 int TreeSize(struct TreeNode* root)
 {
    if(root == NULL)
        return 0;
    int left = TreeSize(root->left);
    int right = TreeSize(root->right);
    return left + right + 1;
 }
 //利用前序遍历的思路开始遍历
 void _preorderTraversal(struct TreeNode* root,int* a,int* i)
 {
    if(root == NULL)
    {
        return;
    }
    a[(*i)++] = root->val;
    _preorderTraversal(root->left,a,i);
    _preorderTraversal(root->right,a,i);

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

另一棵树的子树

左边树里面的的子树都跟右边的树比较一下,一个一个根比较,每一个节点都是根

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

根据一个字符串创建二叉树

#include <stdio.h>
#include <stdlib.h>
typedef struct BTNode
{
    char data;
    struct BTNode* left;
    struct BTNode* right;
}BTNode;
//首先我们需要一个创建树的函数
BTNode* BuyTreeNode(char a)
{
    BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
    newnode->data = a;
    newnode->left = NULL;
    newnode->right = NULL;

    return newnode;
}
BTNode* CreateTree(char* a,int *pi)
{
    if(a[*pi] == '#')
    {
        (*pi)++;
        return NULL;
    }
       
    //我们需要创建一个节点
    //前序遍历创建节点
    BTNode* newnode = BuyTreeNode(a[*pi]);
    (*pi)++;
    newnode->left = CreateTree(a,pi);
    newnode->right = CreateTree(a,pi);

    return newnode;
}

void Inorder(BTNode* root)
{
    if(root == NULL)
        return;
    Inorder(root->left);
    printf("%c ",root->data);
    Inorder(root->right);
}
int main() {
    //首先我们创建一个数组用来存放值
    char* a = (char*)malloc(sizeof(char)*100);
    scanf("%s",a);
    int i = 0;
    //然后构造一个创建树的函数
    BTNode* root = CreateTree(a, &i);
    Inorder(root);
    return 0;
}

层序遍历

void LevelBTree(BTNode* root)
{
	//层序遍历
	assert(root);
	Queue q;
	QueueInit(&q);
	//首先把根节点push进去
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%d", front->data);
		//出来的时候把下一层节点带入队列中
		if (front->left)
			QueuePush(&q,front->left);
		if (front->right)
			QueuePush(&q,front->right);
	}
	QueueDestory(&q);
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值