1.二叉树的前序遍历
二叉树的前序遍历比较简单,但是在力扣上写这个接口需要注意几个点:
int* preorderTraversal(struct TreeNode* root, int* returnSize) {}
- preorderTraversal 的返回值是动态开辟的数组,里面存放的是前序遍历的顺序
- int* returnSize 这个参数记录的是遍历到的数据个数,因为函数的返回值只能有一个,所以我们通它来记录,当用户需要数据个数时,直接查看该指针变量即可
代码:
int TreeSize(struct TreeNode* root){if(root == NULL)return 0;return TreeSize(root->left) + TreeSize(root->right) + 1;
}void _preOrder(struct TreeNode* root, int* a,int* i){if(root == NULL)return;a[*i] = root->val; //记录当前节点,到数组中(*i)++; //数组下标+1_preOrder(root->left,a,i); //接着遍历左子树_preOrder(root->right,a,i); //然后遍历右子树 }//returensize是记录数组的元素个数,我们要返回给用户的是遍历数的数组
int* preorderTraversal(struct TreeNode* root, int* returnSize) {*returnSize = TreeSize(root);//遍历树,得到数据个数int* a = (int*)malloc(sizeof(int) * (*returnSize));//动态开辟数组空间int i = 0;_preOrder(root ,a,&i);//前序遍历return a;}
2.检查两棵树是否相同
思路:
利用前序遍历,先比较当前节点是否相同,紧接着比较左子树与右子树
代码:
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {if(p == NULL && q == NULL) //如果pq都为NULL,返回真return true;if(p == NULL || q == NULL) //代码到这里,只有2种可能,1.pq其中一个为NULL,2两个都不为NULL//如果其中一个为NULL,说明另一个一定不是NULL,则pq不相等,不用return false; //比较了,返回falseif(p->val != q->val) // 代码到这,说明pq都不为NULL,直接比较即可return false; //比较qp相等没有用意义,要看它们不相等,可以直接出结果return isSameTree(q->left,p->left) //在比较左右子树,右子树&& isSameTree(q->right,p->right);
}
3.对称二叉树
思路:
观察示例一:一颗对称的二叉树,我的左子树根节点 == 你的右子树根节点、我的右子树根节点 == 你的左子树根节点。有一个地方不符合此规则,则此树不是对称二叉树
所以示例一是一颗对称二叉树,我们代码则使用递归的方法,先比较当前两棵树的根节点是否相同,在比较这两颗树的左右子树是否对称
代码:
bool _isSymmetric(struct TreeNode* q,struct TreeNode* p)
{//先比较当前两颗子树的根节点是都相同if(p == NULL && q == NULL) return true;if(p == NULL || q == NULL) //代码到这里,只有2种可能,1.pq其中一个为NULL,2两个都不为NULLreturn false;if(p->val != q->val)// 比较根节点是否相同return false;return _isSymmetric(q->left,p->right) //q节点的左子树,与p节点的右子树比&& _isSymmetric(q->right,p->left); //q节点的右子树,与p节点的左子树比
}
bool isSymmetric(struct TreeNode* root) {return _isSymmetric(root->left,root->right);
}
4.另一棵树的子树
思路:
题目给出了root树与subRoot树,让我们看看sybRoot树是否是root树中的一个子树
1.那么我们首先要做的是:如何找出root树的所有子树?
其实这个很简单,我们只需要遍历到root树的每一个节点就相当于找到了root树的所有子树,因为每一个节点都是某棵树的根节点,通过根节点自然得到了一节树
2.找到了所有子树之后我们要做的自然依次与subRoot树比较,看有没有相同的树了
我们前面已经写过检查两颗树是否相同,直接移植过来就可以
代码:
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(q->left,p->left)&& isSameTree(q->right,p->right);
}bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){if(root == NULL)//subRoot树上的节点数量范围是[1, 1000],所以当遍历到的子树为NULL时返回falsereturn false;//当某一个子树的根节点与subRoot根节点相同时,开始比较两棵树是否相同//当两颗树相同则直接出结果,不用接着去找了,返回ture if(root->val == subRoot->val &&isSameTree(root,subRoot))return true;//接着去遍历左子树与右子树,一边找到了就不用再继续找了,整体就是前序遍历的去遍历每一颗子树return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
5.二叉树的构建及遍历
利用,用户输入的数组先构建一颗二叉树,在进行中序遍历即可
代码:
#include <stdio.h>
#include<stdlib.h>
typedef char BTDataType;typedef struct BinaryTreeNode {BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
} BTNode;BTNode* BuyNode(BTDataType x) {BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL) {perror("Buynode()::malloc()");return newnode;}newnode->_data = x;newnode->_left = NULL;newnode->_right = NULL;return newnode;
}// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root) {if (root == NULL) {return;}BinaryTreeInOrder(root->_left);//左子树printf("%c ", root->_data);//根节点BinaryTreeInOrder(root->_right);
}// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a,int* pi) {//根,左子树,右子树if (a[(*pi)] == '#') {(*pi)++;return NULL;}BTNode* newnode = BuyNode(a[(*pi)++]);newnode->_left = BinaryTreeCreate(a,pi);newnode->_right = BinaryTreeCreate(a,pi);return newnode;
}int main() {char arr[101];scanf("%s",arr);int count = 0;BTNode* tree = BinaryTreeCreate(arr,&count); //构建二叉树BinaryTreeInOrder(tree); //中序遍历二叉树return 0;
}
6.翻转二叉树
思路:
依旧是使用递归,先翻转左子树,在翻转右子树。由于翻转后,左右子树的根节点没有动,最后在将根节点翻转即可完成当前树的翻转
代码:
void _invertTree(struct TreeNode* root)
{if(root == NULL)return;_invertTree(root->left); //翻转左子树_invertTree(root->right); //翻转右子树//在将自己左右子树的根节点交换,即可完成翻转struct TreeNode* temp = root->left;root->left = root->right;root->right = temp;
}
struct TreeNode* invertTree(struct TreeNode* root) {_invertTree(root);return root;
}
7.平衡二叉树
平衡二叉树: 每个节点的左右子树的深度相差不超过1
思路:
遍历二叉树的每一个节点,算它们的高度差超过1吗,超过就不是平衡二叉树
代码:
int TreeHight(struct TreeNode* root)//求高度
{if(root == NULL)return 0;int left = TreeHight(root->left);int right = TreeHight(root->right);return left > right ? left + 1 : right + 1;
}//走前序遍历,依次遍历每个节点,并求节点左子树与右子树的高度差 >1?
bool isBalanced(struct TreeNode* root) {if(root == NULL)return true;//比较当前节点左右子树高度差int left = TreeHight(root->left); int right = TreeHight(root->right);if(abs(left-right) > 1)return false;if(isBalanced(root->left) == 0) //遍历左子树return false;if(isBalanced(root->right) == 0) //遍历右子树return false;return true; //代码到这说明它就是一颗平衡二叉树
}