二叉树的创建与三种遍历方式
作为咸鱼,这个学期学习了一种极为重要的数据结构:
二叉树
和之前的线性数据结构比起来,二叉树是非线性的,拥有多样的创建和遍历方式;
刚刚上手的时候,总会觉得有点晕头转向;
加之递归函数又有些生疏,刚开始学习的时候总是会出现一些莫名其妙的报错;
之后笔者在通过自己编写程序以及OJ刷题之后,渐渐,咳咳,自认为掌握了二叉树的基础操作,现在将二叉树的一些知识点整理下来:
那么先从基础的开始:
二叉树的创建与三种遍历方式
首先是定义二叉树节点
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
接下来是最基础的操作,二叉树的创建:
递归创建,要注意节点的空间申请
struct TreeNode* buildTree(struct TreeNode* root)
{
int val;
scanf("%d", &val);
if(val == 0) {
root = nullptr; //指向空节点
return nullptr;
}
root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val = val;
root->left = buildTree(root->left); //创建左子树
root->right = buildTree(root->right); //创建右子树
return root;
}
接下来是二叉树的三种遍历方式,
虽然先根,中根,后根遍历的结果在顺序上差别相当大;
但其实仔细分析遍历过程的话,这三种的递归遍历的思路非常接近;
而在代码上也仅仅只有微妙的差异:
先根遍历:
void scanTreePre(struct TreeNode *root)
{
if(!root) return;
printf("%d ", root->val);
scanTreePre(root->left);
scanTreePre(root->right);
}
中根遍历:
void scanTreeMid(struct TreeNode *root)
{
if(!root) return;
scanTreeMid(root->left);
printf("%d ", root->val);
scanTreeMid(root->right);
}
后根遍历:
void scanTreePost(struct TreeNode *root)
{
if(!root) return;
scanTreePost(root->left);
scanTreePost(root->right);
printf("%d ", root->val);
}
代码非常精简,思路也很清晰,即使用纸笔也可以很快模拟出遍历过程
以下是主函数:
int main()
{
struct TreeNode *root = NULL; //创建二叉树根节点
root = buildTree(root);
printf("preorder is: ");
scanTreePre(root);
printf("\nmidorder is: ");
scanTreeMid(root);
printf("\npostorder is: ");
scanTreePost(root);
return 0;
}
最后附上程序的运行结果