一、二叉树的层次遍历
根据代码随想录提供的思路,利用队列的特性,进行解决,但是c语言没有队列接口,因此需要用数组去模拟队列的用法,使用过程中,有几个点需要注意下:
1 C语言写的函数,returnSIze和 returnColumnSize分别代表的意思,第一个returnSize代表的是有多少个数组,即有多少层,另一个是指一个层里面,有多少个size,即每一个元素的数量;
2 注意root为空的情况,这个每次都忘;
3 malloc buff有那几部分呢:
1)sizeColumnSize需要一个buff保存每一层的数据;
2)保存节点需要一个buff,用来当做队列,进行出队入队的操作;
3)result结果需要一个二维数组保存,但是申请的是一个指针数组,因此里面的指针还需要malloc buff,用来存每一层的数值。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
/**
队列思想
1 root 入队,size记录,然后才进行节点操作;
2 size不为空情况下,出队,保存节点的值,然后保存当前节点的left和right(有情况下)
**/
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
int** result = (int**)malloc(sizeof(int*) * 2010);//超过节点数设置大小
int result_idx = 0;
int* NodeArr = (int*)malloc(sizeof(int) * 1);//root 节点
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 2010);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个用来保存每层多少个vlaue**/
*returnColumnSizes = (int*)malloc(sizeof(int) * 2010);
for(int i = 0; i < 2010; i++)
{
(*returnColumnSizes)[i] = 0;//初始化
}
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
(*returnColumnSizes)[*returnSize] = queue_size;//每层节点的个数
int* Arr = (int* )malloc(sizeof(int) * queue_size);
int arrIdx = 0;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct TreeNode* curNode = NodeList[queue_left];
Arr[arrIdx++] = curNode->val;
/**队列indx往前进一**/
queue_left++;
/**该节点的左右子节点入队列***/
if(curNode->left)
NodeList[queue_right++] = curNode->left;
if(curNode->right)
NodeList[queue_right++] = curNode->right;
queue_size--;
}
result[(*returnSize)++] = Arr;//多少行,就多少个数组
}
return result;
}
二、二叉树的层次遍历2
在1的基础上,做下翻转,C语言中写法需要注意:就是对应每一层的size也要转换(一直没看出问题来!!)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
void swap(int** arr, int size, int* lenarr)//change 每一层的size
{
int left = 0;
int right = size -1;
while(left < right)
{
int* tmp = arr[right];
int len_tmp = lenarr[right];
arr[right] = arr[left];
lenarr[right] = lenarr[left];
arr[left] = tmp;
lenarr[left] = len_tmp;
left++;
right--;
}
}
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
int** result = (int**)malloc(sizeof(int*) * 2010);//超过节点数设置大小
int result_idx = 0;
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 2010);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个用来保存每层多少个vlue**/
*returnColumnSizes = (int*)malloc(sizeof(int) * 2010);
for(int i = 0; i < 2010; i++)
{
(*returnColumnSizes)[i] = 0;//初始化
}
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
(*returnColumnSizes)[*returnSize] = queue_size;//每层节点的个数
int* Arr = (int* )malloc(sizeof(int) * queue_size);
int arrIdx = 0;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct TreeNode* curNode = NodeList[queue_left];
Arr[arrIdx++] = curNode->val;
/**队列indx往前进一**/
queue_left++;
/**该节点的左右子节点入队列***/
if(curNode->left)
NodeList[queue_right++] = curNode->left;
if(curNode->right)
NodeList[queue_right++] = curNode->right;
queue_size--;
}
result[(*returnSize)++] = Arr;//多少行,就多少个数组
}
swap(result, *returnSize, *returnColumnSizes);
return result;
}
三、199.二叉树的右视图
思路1:在层序遍历的基础上进行修改,因为已经拿到每一次的数组元素了,右视图,肯定是每一层的数组元素的最大indx对应的value;
/**思路1: 层序遍历基础上进行操作,因为保留了每一层的数据分布,那么最右的一定是每一层arr的indx最大那个**/
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
int** result = (int**)malloc(sizeof(int*) * 201);//超过节点数设置大小
int result_idx = 0;
int* NodeArr = (int*)malloc(sizeof(int) * 1);//root 节点
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 201);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个用来保存每层多少个vlue**/
*returnColumnSizes = (int*)malloc(sizeof(int) * 2010);
for(int i = 0; i < 2010; i++)
{
(*returnColumnSizes)[i] = 0;//初始化
}
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
(*returnColumnSizes)[*returnSize] = queue_size;//每层节点的个数
int* Arr = (int* )malloc(sizeof(int) * queue_size);
int arrIdx = 0;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct TreeNode* curNode = NodeList[queue_left];
Arr[arrIdx++] = curNode->val;
/**队列indx往前进一**/
queue_left++;
/**该节点的左右子节点入队列***/
if(curNode->left)
NodeList[queue_right++] = curNode->left;
if(curNode->right)
NodeList[queue_right++] = curNode->right;
queue_size--;
}
result[(*returnSize)++] = Arr;//多少行,就多少个数组
}
return result;
}
int* rightSideView(struct TreeNode* root, int* returnSize) {
/**初始化malloc题目上限个数**/
int* result = (int*)malloc(sizeof(int) * 101);
int* arrlen = (int*)malloc(sizeof(int) * 101);
int** array = (int**)malloc(sizeof(int*) * 101);
for(int i = 0; i < 101; i++)
{
array[i] = calloc(101, sizeof(int));
}
int returnlen = 0;
array = levelOrder(root, &returnlen, &arrlen);
/**获取array数据,找到每个数组 indx最大那个**/
for(int i = 0; i < returnlen; i++)
{
result[i] = array[i][arrlen[i] -1];
}
*returnSize = returnlen;
return result;
}
思路2:还是利用队列的思想,可以思考,每一层都记录了一个size,当size减小到0时候,此时该节点就是要找的右视图节点。
int* rightSideView(struct TreeNode* root, int* returnSize) {
int* result = (int*)malloc(sizeof(int) * 201);//超过节点数设置大小
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 201);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
// int arrIdx = 0;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct TreeNode* curNode = NodeList[queue_left];
//result[(*returnSize)++] = curNode->val;
/**队列indx往前进一**/
queue_left++;
/**该节点的右子节点入队列***/
if(curNode->left)
{
NodeList[queue_right++] = curNode->left;
}
if(curNode->right)
{
NodeList[queue_right++] = curNode->right;
}
queue_size--;
/**此时代表当前层已经在最后一个节点了**/
if(queue_size == 0)
{
result[(*returnSize)++] = curNode->val;
}
}
}
return result;
}
四、二叉树的层平均值
思路1依然是在层次遍历基础上进行计算,然后返回平均值
思路2,每次记录curNode的value,去累加到一个sum上,当此层遍历结束后,存下来;
double* averageOfLevels(struct TreeNode* root, int* returnSize) {
double* result = (double*)malloc(sizeof(double) * 10001);//超过节点数设置大小 2^N -1
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 10001);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
double sum = 0.0;
int single_size = queue_size;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct TreeNode* curNode = NodeList[queue_left];
sum += (double)curNode->val;
//result[(*returnSize)++] = curNode->val;
/**队列indx往前进一**/
queue_left++;
/**该节点的右子节点入队列***/
if(curNode->left)
{
NodeList[queue_right++] = curNode->left;
}
if(curNode->right)
{
NodeList[queue_right++] = curNode->right;
}
queue_size--;
}
/**此时代表当前层遍历结束**/
// printf("sum = %f mum = %d\n", sum, single_size);
result[(*returnSize)++] = sum/single_size;
}
return result;
}
四、N叉树的层次遍历
N叉树的层次遍历,和二叉树的层次遍历,不同之处在于,N叉树是用一个节点数组从左到右来保存自己的孩子节点,因此使用队列去入队的时候,就使用遍历的方式,相当于从左至右把当前孩子节点入队。
/**
* Definition for a Node.
* struct Node {
* int val;
* int numChildren;
* struct Node** children;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
/**
思路:根据二叉树的层次遍历,N叉树改变了左右子树,这里需要注意
**/
int** levelOrder(struct Node* root, int* returnSize, int** returnColumnSizes) {
int** result = (int**)malloc(sizeof(int*) * 1001);//超过节点数设置大小
//int result_idx = 0;
//int* NodeArr = (int*)malloc(sizeof(int) * 1);//root 节点
struct Node** NodeList = (struct Node**)malloc(sizeof(struct Node*) * 10001);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个用来保存每层多少个vlaue**/
*returnColumnSizes = (int*)malloc(sizeof(int) * 1001);
for(int i = 0; i < 1001; i++)
{
(*returnColumnSizes)[i] = 0;//初始化
}
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
(*returnColumnSizes)[*returnSize] = queue_size;//每层节点的个数
int* Arr = (int* )malloc(sizeof(int) * queue_size);
int arrIdx = 0;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct Node* curNode = NodeList[queue_left];
Arr[arrIdx++] = curNode->val;
/**队列indx往前进一**/
queue_left++;
/**该节点的孩子节点入队列***/
for(int i = 0; i < curNode->numChildren; i++)
{
NodeList[queue_right++] = curNode->children[i];
}
// if(curNode->left)
// NodeList[queue_right++] = curNode->left;
// if(curNode->right)
// NodeList[queue_right++] = curNode->right;
queue_size--;
}
result[(*returnSize)++] = Arr;//多少行,就多少个数组
}
return result;
}
五、515 每个树行中找最大值
思路还是在层次遍历基础上,每一层遍历时候,找到每一层的最大值。
/**每一层遍历,去比较最大值,直到这一层结束**/
int* largestValues(struct TreeNode* root, int* returnSize) {
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 10000);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个保存多少行**/
*returnSize = 0;
if(root == NULL)
{
return NULL;
}
//queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
//(*returnColumnSizes)[*returnSize] = queue_size;//每层节点的个数
int* result = (int* )malloc(sizeof(int) * 1000);//2^N = 100000
int arrIdx = 0;
int Max = 0;
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
int* Arr = (int* )malloc(sizeof(int) * queue_size);
int Max_value = INT_MIN;
while(queue_size > 0)
{
/**把当前节点的value放入数组(出队列)**/
struct TreeNode* curNode = NodeList[queue_left];
//Arr[arrIdx++] = curNode->val;
if(Max_value < curNode->val)
{
Max_value = curNode->val;
}
/**队列indx往前进一**/
queue_left++;
/**该节点的左右子节点入队列***/
if(curNode->left)
NodeList[queue_right++] = curNode->left;
if(curNode->right)
NodeList[queue_right++] = curNode->right;
queue_size--;
}
result[(*returnSize)++] = Max_value;//多少行,就多少个数组
}
return result;
}
五、116. 填充每个节点的下一个右侧节点指针
思路:每一层的节点指向下一个节点,因此需要找到当前节点和下一个节点,在处理过程,没有考虑queue size的情况,导致计算当前层的时候,可能访问到其他位置了,如果不限制size大于0情况下去找next node,可能找到的next node就是其他层的节点,也可能没有值。
struct Node* connect(struct Node* root) {
//int** result = (int**)malloc(sizeof(int*) * 2010);//超过节点数设置大小
struct Node** NodeList = (struct Node**)malloc(sizeof(struct Node*) * 100000);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个用来保存每层多少个value**/
int index = 0;
int *returnSize = &index;
if(root == NULL)
{
return NULL;
}
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
//struct Node* preNode = (struct Node*)malloc(sizeof(struct Node));
while(queue_size > 0)
{
/**需要保存当前节点**/
struct Node* curNode = NodeList[queue_left];
/**队列indx往前进一**/
queue_left++;
/**该节点的左右子节点入队列***/
if(curNode->left)
NodeList[queue_right++] = curNode->left;
if(curNode->right)
NodeList[queue_right++] = curNode->right;
queue_size--;
if(queue_size > 0)
{
/**遍历下一个 Node**/
struct Node* nextNode = NodeList[queue_left];
curNode->next = nextNode;
}
else
{
curNode->next = NULL;
}
}
//result[(*returnSize)++] = Arr;//多少行,就多少个数组
}
return root;
}
六、117. 填充每个节点的下一个右侧节点指针 II
和上题做法一样
七、104. 二叉树的最大深度
按照层序遍历来说,如果每一层都能遍历得到,那么层数就是最大的深度
八、111 二叉树最小深度
int minDepth(struct TreeNode* root) {
struct TreeNode** NodeList = (struct NoTreeNodede**)malloc(sizeof(struct Node*) * 100000);
int queue_left = 0, queue_right = 0;//一个用于对头移动,一个用于队尾 index
NodeList[queue_right++] = root;
int queue_size = 0;
/**这个用来保存每层多少个value**/
int index = 0;
int *returnSize = &index;
if(root == NULL)
{
return 0;
}
int depth = 0;
while(queue_right > queue_left)//队列不为空
{
queue_size = queue_right - queue_left;//获取当前queue size
//printf("size is %d L=%d, R=%d\n", queue_size, queue_left, queue_right);
//struct Node* preNode = (struct Node*)malloc(sizeof(struct Node));
bool left_flg = false;
bool right_flg = false;
while(queue_size > 0)
{
/**需要保存当前节点**/
struct TreeNode* curNode = NodeList[queue_left];
left_flg = false;
right_flg = false;
/**队列indx往前进一**/
queue_left++;
/**该节点的左右子节点入队列***/
if(curNode->left)
NodeList[queue_right++] = curNode->left;
else
left_flg = true;
if(curNode->right)
NodeList[queue_right++] = curNode->right;
else
right_flg = true;
//如果当前节点没有左右子孩子,那么终止于此,不要再遍历当前层后面的节点了
if(left_flg && right_flg)
{
break;
}
queue_size--;
}
depth++;
//printf("depth = %d\n", depth);
//当前层的一个节点无后继孩子,那么就是最短的深度
if(left_flg && right_flg)
{
break;
}
}
return depth ;
}
九、翻转二叉树
方法1-递归法
递归时候swap函数需要注意,因为需要指针传递,我们需要更换的是指针,所以参数是指针的指针,才能改变指针;
/**
1 递归法: 思路就是翻转左右节点,注意递归三要素
**/
void reserve(struct TreeNode** left, struct TreeNode** right)
{
struct TreeNode* tmp_node = *right;
*right = *left;
*left = tmp_node;
}
struct TreeNode* invertTree(struct TreeNode* root) {
if(root == NULL)
return NULL;
reserve(&(root->left), &(root->right));
invertTree(root->left);
invertTree(root->right);
return root;
}
方法2-迭代法
首先得理清楚前序遍历的流程,然后根据此流程的基础上进行修改:
/**注意:指针传递,才能改变节点的值,即地址值**/
void reserve(struct TreeNode** left, struct TreeNode** right)
{
struct TreeNode* tmp_node = *right;
*right = *left;
*left = tmp_node;
}
struct TreeNode* invertTree(struct TreeNode* root) {
/**用数组模拟栈**/
int stk_base = -1;//栈底位置
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 101);
NodeList[++stk_base] = root;
if(root == NULL)
{
return NULL;
}
/**栈不为空时候**/
while(stk_base > -1)
{
//pop出栈
struct TreeNode* curNode = NodeList[stk_base];
stk_base--;//相当于出栈
reserve(&(curNode->left), &curNode->right);//翻转二叉树
//把右节点 左节点入栈
if(curNode->right)
NodeList[++stk_base] = curNode->right;
if(curNode->left)
NodeList[++stk_base] = curNode->left;
}
return root;
}
其次,根据层次遍历的思路,来翻转二叉树。
void reserve(struct TreeNode** left, struct TreeNode** right)
{
struct TreeNode* tmp_node = *right;
*right = *left;
*left = tmp_node;
}
struct TreeNode* invertTree(struct TreeNode* root) {
/**用数组模拟队列**/
//int stk_base = -1;//栈底位置
int q_left = 0, q_right = 0;
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 101);
NodeList[q_right++] = root;
if(root == NULL)
{
return NULL;
}
/**队列不为空时候**/
while(q_right > q_left)
{
int q_size = q_right - q_left;
while(q_size > 0)
{
//出队列
struct TreeNode* curNode = NodeList[q_left];
q_left++;//相当出队列
reserve(&(curNode->left), &curNode->right);
//把右节点 左节点入队列
if(curNode->right)
NodeList[q_right++] = curNode->right;
if(curNode->left)
NodeList[q_right++] = curNode->left;
q_size--;
}
}
return root;
}
十、对称二叉树
该题目依然可以用递归和迭代进行解决:
1 递归法:主要是要理清楚return的情况,其一,如果左右子树有一个是空的,那么必然不对称,没必要比较后面的;其二,如果左右子树都是空的,那么可以理解成只有root节点,是对称的,可以返回ture;其三,如果左右子树都存在,那么如果两个的值不相等,也没有必要再比较后面的节点了,可以直接返回。这里去思考的时候,多加了一个else的情况,就是两个节点值相等,返回ture,这里问题点就在于这里返回之后,导致后面节点无法遍历,如果后面不对称,那么会导致结果出错。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**递归:需要注意以下几个情况:
1 二叉树为空
2 二叉树不对齐
**/
bool commpre(struct TreeNode* left, struct TreeNode* right)
{
/**不满足条件的情况**/
if((left == NULL && right != NULL) || (right == NULL && left != NULL))
{
return false;//某一个为空 另一个不为空
}
else if(left == NULL && right == NULL)
{
/**两个都为空,对称情况 满足**/
return true;
}
else if(left->val != right->val)//两个不为空,且值不等
{
return false;
}
/**后面不能判断,因为只是当前层结果是对称的,但是如果后面还有节点,那么会直接return,后面无法对比**/
// else if(left->val == right->val)
// {
// printf("%d - %d\n", left->val, right->val);
// return true;
// }
bool outside = commpre(left->left, right->right);
bool intside = commpre(left->right, right->left);
return outside && intside;
}
bool isSymmetric(struct TreeNode* root) {
if(!root)
{
return true;
}
struct TreeNode* left = root->left;
struct TreeNode* right = root->right;
bool result = commpre(left, right);
return result;
}
2 迭代法:
可以使用队列或者栈的思想,以队列为例:
bool isSymmetric(struct TreeNode* root) {
/**使用数组迭代**/
if(root == NULL)
{
return true;
}
//1.malloc buff保存节点
struct TreeNode** NodeList = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 1001);
int queue_left = 0, queue_right = 0;
NodeList[queue_right++] = root->left;//保存左节点
NodeList[queue_right++] = root->right;//保存右节点
/**队列不为空**/
while(queue_right > queue_left)
{
int queue_size = queue_right - queue_left;
while(queue_size > 0)
{
/**节点出队列**/
struct TreeNode* node_left = NodeList[queue_left++];
struct TreeNode* node_right = NodeList[queue_left++];
if(!node_left && !node_right)
{
//return true;
//一样的处理 这里不能直接返回,可能开始的节点对称,后面的不对称,要遍历完
queue_size -=2;//出队
continue;
}
//其中一个不为空
if(!node_left && node_right || node_left && !node_right)
{
return false;
}
if(node_left->val != node_right->val)
{
return false;
}
/**入队**/
//先把外围节点对入队
NodeList[queue_right++] = node_left->left;
NodeList[queue_right++] = node_right->right;
//把内侧节点对加入队列
NodeList[queue_right++] = node_left->right;
NodeList[queue_right++] = node_right->left;
queue_size -=2;//出队2个 size需要减去2个
}
}
return true;
}
这里需要注意:和层序遍历区别,层序遍历是每次获取当前节点,但此题目是需要同时获取左右节点;另外,如果左右节点为空,需要把size剪掉,这样满足出队要求,后面再循环判断时候,不会再入队遍历,导致空指针访问出错。
十一、总结
最近关于二叉树的训练,总结下:
1 遍历方式:1)前中后序遍历,即深度优先遍历,可以使用栈的方式进行迭代,但是前中后续迭代方式可能代码无法统一,因此需要加入一个空节点来记录,可以参考代码随想录;
2 层序遍历:使用队列的思想进行遍历,即广度优先遍历。
两种迭代方式,可以对比着学习,便于进一步理解。
除了迭代方式,也可以用递归的方式进行解决,需要注意递归的返回,递归中止条件,以及递归参数等信息。