二叉树的前序遍历,中序遍历与后序遍历——这是我个人所认为的在二叉树的学习中最难的一个知识要点,故与此记录。
至于为什么觉得它难,那就是历史遗留问题了,关于我饭点的经常性走神以及过去我对于某些知识点的记忆理解方法,其中实在过于复杂,在此不表。
前序遍历,中序遍历,后序遍历。
在理解这三个知识点的时候我们最好不要将它们分开来看,而是将它们放在一起,比较之中寻不同,从而记忆理解。
先看看比较官方的说法:
1. 前序遍历 (Preorder Traversal 亦称先序遍历 )—— 访问根结点的操作发生在遍历其左右子树之前。2. 中序遍历 (Inorder Traversal)—— 访问根结点的操作发生在遍历其左右子树之中(间)。3. 后序遍历 (Postorder Traversal)—— 访问根结点的操作发生在遍历其左右子树之后。
在记忆时,我们应该重点关注于其名字,前序,中序,后序。
这前,中,后三个字刚好对应了三者遍历规则中根节点的遍历优先度。
前序遍历——根->左->右
中序遍历——左->根->右
后序遍历——左->右->根
到了这一点看起来可能还是有些抽象,但如果结合起相关的代码来看则清晰明了的多了——如果你对递归理解透彻的话。
前序遍历
——输出根结点
——递归进入左子树
——递归进入右子树
void BinaryTreePrevOrder(BTNode* root) {
if (root != NULL) {
putchar(root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
}
中序遍历
——递归进入左子树
——输出根节点
——递归进入右子树
void BinaryTreeInOrder(BTNode* root) {
if (root != NULL) {
BinaryTreeInOrder(root->_left);
putchar(root->_data);
BinaryTreeInOrder(root->_right);
}
}
后序遍历
——递归进入左子树
——递归进入右子树
——输出根节点
void BinaryTreePostOrder(BTNode* root) {
if (root != NULL) {
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
putchar(root->_data);
}
}
附二叉树相关代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi) {
if ('#' == a[*pi] || *pi >= n) {
(*pi)++;
return NULL;
}
BTNode* bt = (BTNode*)malloc(sizeof(BTNode));
bt->_data = a[*pi];
(*pi)++;
bt->_left = BinaryTreeCreate(a, n, pi);
bt->_right = BinaryTreeCreate(a, n, pi);
return bt;
}
// 二叉树销毁
void BinaryTreeDestory(BTNode** root) {
if (*root)
{
BinaryTreeDestory(&(*root)->_left);
BinaryTreeDestory(&(*root)->_right);
free(*root);
*root = NULL;
}
}
// 二叉树节点个数
int BinaryTreeSize(BTNode* root) {
if (NULL == root) {
return 0;
}
return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root) {
if (NULL == root) {
return 0;
}
if (NULL == root->_left && NULL == root->_right) {
return 1;
}
return BinaryTreeLeafSize(root) + BinaryTreeLeafSize(root);
}
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k) {
if (root == NULL) {
return 0;
}
if (k == 0) {
return 1;
}
return BinaryTreeLevelKSize(root->_left, k -1) + BinaryTreeLevelKSize(root->_right, k - 1);
}
// 二叉树查找值为x的节点
void BinaryTreeFind(BTNode* root, BTDataType x) {
if (root == NULL) {
return ;
}
if (x == root->_data) {
printf("找到该结点");
return ;
}
BinaryTreeFind(root->_left, x);
BinaryTreeFind(root->_right, x);
}
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root) {
if (root != NULL) {
putchar(root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
}
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root) {
if (root != NULL) {
BinaryTreeInOrder(root->_left);
putchar(root->_data);
BinaryTreeInOrder(root->_right);
}
}
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root) {
if (root != NULL) {
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
putchar(root->_data);
}
}
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root); {
Queue qu;
BTNode * cur;
QueueInit(&qu);
QueuePush(&qu, root);
while (!QueueIsEmpty(&qu)) {
cur = QueueTop(&qu);
putchar(cur->_data);
if (cur->_left != NULL) {
QueuePush(&qu, cur->_left);
}
if (cur->_right != NULL) {
QueuePush(&qu, cur->_right);
}
QueuePop(&qu);
}
QueueDestory(&qu);
}
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root) {
Queue qu;
BTNode * cur;
int tag = 0;
QueueInit(&qu);
QueuePush(&qu, root);
while (!QueueIsEmpty(&qu)) {
cur = QueueTop(&qu);
putchar(cur->_data);
if (cur->_right && !cur->_left) {
return 0;
}
if (tag && (cur->_right || cur->_left)) {
return 0;
}
if (cur->_left != NULL) {
QueuePush(&qu, cur->_left);
}
if (cur->_right != NULL) {
QueuePush(&qu, cur->_right);
}
else {
tag = 1;
}
QueuePop(&qu);
}
QueueDestory(&qu);
return 1;
}
int main () {
char* a = "ABD##E#H##CF##G##";
int pi = 0;
BTNode* bt = BinaryTreeCreate(a, 17, &pi);
BinaryTreePrevOrder(bt);
printf("\n");
BinaryTreePostOrder(bt);
printf("\n");
BinaryTreeInOrder(bt);
return 0;
}