C++二叉树的遍历

遍历:顺着某一条搜索路径,使得二叉树中的每一个结点有且仅有被访问一次,叫做遍历,或者周游。访问的含义非常广泛。可以认为在不破坏原来结构的基础上对结点数值进行取出和修改等。

遍历的目的:在规定遍历顺序后,可以将二叉树这种非线性的数据结构转换为线性排列进行处理

遍历的意义:二叉树的增删改查均需要遍历。遍历,是二叉树运算的核心。

遍历方法:二叉树是一种典型的递归结构,每一个结点内部,均有两个与节点类型相同的指针。因此,我们只要依次遍历二叉树的左子树,根节点和右子树,即可完成整个遍历

根据不同的遍历顺序,可以将遍历方法规定为:

DLR:根左右,先根遍历

LDR:左根右,中根遍历

LRD:左右根,后根遍历

左右字数的遍历顺序不变,仅改变根的位置。

对于每一个结点,都会有一个自己的遍历函数。该遍历函数的遍历顺序规定为上述遍历顺序的某一种。找到根节点且根节点不为空时,可以调用结点的遍历函数,遍历函数依次对该结点的左右子树遍历。例如:找到左子树结点后,调用结点遍历函数,可以对左子树的左子树,根节点和右子树进行遍历....以此类推,可以完成树所有节点的遍历。

先序遍历

顺序:找到二叉树中指向根结点得指针,进而找到根节点

(1)当该结点不是NULL时,可以进行如下操作,否则终止输出结点数值的操作

(2)先将访问到得结点得数值输出

(3)访问该结点得左结点,当该节点下一个访问目标为空时,输出结点数值,重复(1)(2)(3)(4)

(4)访问该节点得右节点,当该节点下一个访问目标为空时,输出结点数值,重复(1)(2)(3)(4)

例子:

 中序遍历

顺序:找到二叉树中指向根结点得指针,进而找到根节点

(1)当该结点不是NULL时,可以进行如下操作,否则终止输出数值的操作

(2)当此节点不为空时,先不输出该节点的值,应先访问该结点得左结点,当下一个访问目标时叶子节点时,可以进行输出操作,并重复(1),(2),(3),(4)

(3)再将该结点得数值输出

(4)最后访问该节点得右节点,下一个访问目标时叶子节点时,可以进行输出操作,重复(1)(2)(3)(4)

 注意:这里的顺序可能看上去有些混乱,因为即使找到了结点,我们也不应该直接输出结点内的数值,而是一直往左边寻找左子树的最左叶子结点。输出结点数值的终极条件为:左子树只连接了叶子节点,根节点连接在上一个已经输出的节点之上,右子树输出条件在根节点之后

后序遍历

顺序:找到二叉树中指向根结点得指针,进而找到根节点

(1)当该结点不是NULL时,可以进行如下操作,否则终止输出数值的操作

(2)当此节点不为空时,先不输出该节点的值,应先访问该结点得左结点,当下一个访问目标是叶子节点时,可以进行输出操作,并重复(1),(2),(3),(4)

(3)再访问该节点得左节点,下一个访问目标为叶子节点时,可以进行输出操作,重复(1)(2)(3)(4)

(4)再将该结点得数值输出

注意:这里的顺序也有点乱,但一定要清楚,我们在找到节点的第一个操作应该是判断该结点的左子树是否为空,然后右子树,再进行剩下的操作。

练习:

C++中的二叉树遍历算法主要包括三种方式:前序遍历、中序遍历和后序遍历。此外,还有层次遍历,但通常我们讨论的是前三种。 1. 前序遍历(Pre-order Traversal):首先访问根节点,然后递归地先序遍历左子树,接着递归地先序遍历右子树。遍历顺序为根节点 -> 左子树 -> 右子树。 2. 中序遍历(In-order Traversal):首先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。对于二叉搜索树,中序遍历可以得到一个有序的元素序列。遍历顺序为左子树 -> 根节点 -> 右子树。 3. 后序遍历(Post-order Traversal):首先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。遍历顺序为左子树 -> 右子树 -> 根节点。 以下是三种遍历算法的简单示例代码: ```cpp struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; void preOrder(TreeNode* root) { if (root == nullptr) return; // 访问根节点 visit(root); // 遍历左子树 preOrder(root->left); // 遍历右子树 preOrder(root->right); } void inOrder(TreeNode* root) { if (root == nullptr) return; // 遍历左子树 inOrder(root->left); // 访问根节点 visit(root); // 遍历右子树 inOrder(root->right); } void postOrder(TreeNode* root) { if (root == nullptr) return; // 遍历左子树 postOrder(root->left); // 遍历右子树 postOrder(root->right); // 访问根节点 visit(root); } ``` 在实际应用中,可能还需要根据具体情况进行变体处理,比如非递归实现,使用栈等数据结构来模拟递归过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值