一、树的层序遍历
层序遍历的实现:
1.依赖于队列的数据结构
2.核心怎么实现:
1)创建一个队列的容器对象。
2)判断根节点是否为空,不为空则添加根节点到队列中。
3)遍历是一个循环性的工作,写一个死循环,死循环的第一步就是跳出死循环的条件:当队列中没有东西时退出(换句话说,没东西可遍历了)。
4)每弹出一个元素,再访问(就是进行符合场景的操作),最后添加两边的左右子节点(如果不为空的话)。
代码实现:
队列的代码:
#pragma once#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<stdbool.h>typedef struct BinaryTreeNode* QDataType;typedef struct QueueNode
{struct QueueNode* _pNext;QDataType _val;
}QNode;typedef struct Queue
{QNode* _front;QNode* _rear;int size;
}Queue;void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);// 队尾插入
void QueuePush(Queue* pq, QDataType x);
// 队头删除
void QueuePop(Queue* pq);// 取队头和队尾的数据
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);队尾插入
//void QueuePush(QNode** pphead, QNode** pptail, QDataType x);队头删除
//void QueuePop(QNode** pphead, QNode** pptail);
#include"Queue.h"
// 初始化队列
void QueueInit(Queue* q)
{assert(q);q->_front = NULL;q->_rear = NULL;q->size = 0;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* tmp = (QNode*)malloc(sizeof(QNode));if (tmp == NULL){perror("malloc fail");return;}else{tmp->_data = data;tmp->_pNext = NULL;}if (q->_rear == NULL){q->_front = q->_rear = tmp;}else{q->_rear->_pNext = tmp;q->_rear = tmp;}q->size++;
}
// 队头出队列
void QueuePop(Queue* q)
{assert(q);assert(q->_front);assert(q->size != 0);if (q->_front->_pNext == NULL)//只有一个节点{free(q->_front);q->_front = q->_rear = NULL;}else{QNode* next = q->_front->_pNext;free(q->_front->_pNext);q->_front = next;}q->size--;
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{assert(q);assert(q->_front);return q->_front->_data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{assert(q);assert(q->_rear);return q->_rear->_data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{assert(q);return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}
// 销毁队列
void QueueDestroy(Queue* q)
{QNode* tmp = q->_front;while (tmp != NULL){QNode* next = tmp->_pNext;free(tmp);tmp = next;}q->_front = q->_rear = NULL;q->size = 0;
}
void TreeLevelOrder(BTNode* root)//层序遍历
{Queue pq;QueueInit(&pq);if (root)QueuePush(&pq, root);while (!QueueEmpty(&pq)){BTNode* front = QueueFront(&pq);QueuePop(&pq);printf("%d ", front->_data);if (front->_left)QueuePush(&pq, front->_left);if (front->_right)QueuePush(&pq, front->_right);}QueueDestroy(&pq);
}
二、平衡二叉树的判断
这道题中的平衡二叉树的定义是:二叉树的每个节点的左右子树的高度差的绝对值不超过 111,则二叉树是平衡二叉树。根据定义,一棵二叉树是平衡二叉树,当且仅当其所有子树也都是平衡二叉树,因此可以使用递归的方式判断二叉树是不是平衡二叉树,
int maxDepth(struct TreeNode* root){return root ? 1 + fmax(maxDepth(root->left) , maxDepth(root->right)) : 0;
}bool isBalanced(struct TreeNode* root){if(root == NULL)return true;int left = maxDepth(root->left);int right = maxDepth(root->right);return abs(left - right) < 2&& isBalanced(root->left)&& isBalanced(root->right);
}
三、树的反转
这是一道很经典的二叉树问题。显然,我们从根节点开始,递归地对树进行遍历,并从叶子节点先开始翻转。如果当前遍历到的节点 root 的左右两棵子树都已经翻转,那么我们只需要交换两棵子树的位置,即可完成以 root为根节点的整棵子树的翻转。
/*** 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=root->left;root->left=root->right;root->right=tmp;invertTree(root->left);invertTree(root->right);return root;
}