- 定义
二叉树是一种特殊的树形数据结构,其中每个节点最多有两个子节点,通常被称为左子节点和右子节点。
二叉树是有限个元素的集合,该集合要么为空(称为空二叉树),要么由一个根元素和两个被分别称为左子树和右子树的不相交的二叉树组成。
图1.二叉树的图示
- 链式存储结构:二叉树的链式存储结构通常由节点组成,每个节点包含一个数据字段和两个指针字段。数据字段用于存储节点值,两个指针字段分别指向左子节点和右子节点。如果某个节点没有子节点,那么相应的指针字段就为NULL。
在C语言中,二叉树的链式存储结构可以定义如下:
typedef struct Node {
int data;
struct Node* left;
struct Node* right;
} Node;
图2.二叉树的链式存储结构
遍历方法:二叉树有三种基本的遍历方法:前序遍历、中序遍历和后序遍历。
1. 先序遍历:首先访问根节点,然后前序遍历左子树,最后前序遍历右子树。
void preOrder(Node* root) {
if (root != NULL) {
printf("%d ", root->data);
preOrder(root->left);
preOrder(root->right);
}
}
2. 中序遍历:首先中序遍历左子树,然后访问根节点,最后中序遍历右子树。
void inOrder(Node* root) {
if (root != NULL) {
inOrder(root->left);
printf("%d ", root->data);
inOrder(root->right);
}
}
3. 后序遍历:首先后序遍历左子树,然后后序遍历右子树,最后访问根节点。
void postOrder(Node* root) {
if (root != NULL) {
postOrder(root->left);
postOrder(root->right);
printf("%d ", root->data);
}
}
- 创建二叉树和进行遍历的步骤
1. 先定义二叉树结构体BTnode,包括数据data和左右子节点Lchild和Rchild。
2. 然后定义CreatNode函数,用于创建新的二叉树节点,并初始化节点的数据和左右子节点。
3. 接着定义preorder、inorder和postorder三个函数,分别实现先序遍历、中序遍历和后序遍历的功能。
4. 在main函数中,创建一个二叉树,并初始化节点的数据和左右子节点。
5. 最后调用preorder、inorder和postorder三个函数,分别输出先序遍历、中序遍历和后序遍历的结果。
图3.结果
- 在编写中容易出现的问题及解决方法
在编写主函数的初始化节点的数据和左右子节点这一过程时,没有将无左右子节点的叶子的情况说明清楚导致出现问题,解决方法是将代码补充完整,用‘.’来说明清楚。
- 总结体会
通过编写这个程序,深刻理解了二叉树的遍历方式以及递归的思想。二叉树的遍历方式有先序遍历、中序遍历和后序遍历,每种遍历方式都有其特定的输出顺序。而递归是实现二叉树遍历的核心思想,通过递归函数不断访问左右子节点,直到遇到空节点为止。
- 代码部分
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
char data;
struct Node *Lchild;
struct Node *Rchild;
}BTnode;
BTnode *CreatNode(char data){
BTnode *newnode=(BTnode*)malloc(sizeof(BTnode));
if(newnode==NULL)
exit(1);
newnode->data=data;
newnode->Lchild=NULL;
newnode->Rchild=NULL;
return newnode;
}
void preorder(BTnode *root)
{
if(root==NULL)
return;
else{
printf("%c",root->data);
preorder(root->Lchild);
preorder(root->Rchild);
}
}
void inorder(BTnode *root)
{
if(root==NULL)
return;
else{
inorder(root->Lchild);
printf("%c",root->data);
inorder(root->Rchild);
}
}
void postorder(BTnode *root)
{
if(root==NULL)
return;
else{
postorder(root->Lchild);
postorder(root->Rchild);
printf("%c",root->data);
}
}
int main()
{
BTnode *root=CreatNode('A');
root->Lchild=CreatNode('B');
root->Lchild->Lchild=CreatNode('D');
root->Lchild->Rchild=CreatNode('.');
root->Lchild->Lchild->Lchild=CreatNode('.');
root->Lchild->Lchild->Rchild=CreatNode('G');
root->Lchild->Lchild->Rchild->Lchild=CreatNode('.');
root->Lchild->Lchild->Rchild->Rchild=CreatNode('.');
root->Rchild=CreatNode('C');
root->Rchild->Lchild=CreatNode('E');
root->Rchild->Rchild=CreatNode('F');
root->Rchild->Rchild->Lchild=CreatNode('.');
root->Rchild->Rchild->Rchild=CreatNode('.');
root->Rchild->Lchild->Lchild=CreatNode('.');
root->Rchild->Lchild->Rchild=CreatNode('H');
root->Rchild->Lchild->Rchild->Lchild=CreatNode('.');
root->Rchild->Lchild->Rchild->Rchild=CreatNode('.');
printf("先序遍历:");
preorder(root);
printf("\n");
printf("中序遍历:");
inorder(root);
printf("\n");
printf("后序遍历:");
postorder(root);
printf("\n");
return 0;
}