目录
树结构及其算法-二叉树遍历
一、中序遍历
二、后序遍历
三、前序遍历
C++代码
树结构及其算法-二叉树遍历
我们知道线性数组或链表都只能单向从头至尾遍历或反向遍历。所谓二叉树的遍历(Binary Tree Traversal),简单的说法就是访问树中所有的节点各一次,并且在遍历后将树中的数据转化为线性关系。对于一棵简单的二叉树节点来说,每个节点都可分为左、右两个分支,可以有ABC、ACB、BAC、BCA、CAB和CBA六种遍历方法。
如果按照二叉树的特性,一律从左向右遍历,就只剩下3种遍历方式,分别是BAC、ABC、BCA。这三种方式的命名与规则如下:
- 中序遍历(Inorder Traversal,BAC):左子树--树根--右子树
- 前序遍历(Preorder Traversal,ABC):树根--左子树--右子树
- 后序遍历(Postorder Traversal,BCA):左子树--右子树--树根
对于这3种遍历方式,大家只需要记住树根的位置,就不会把前序、中序和后序搞混了。例如,中序法是树根在中间,前序法是树根在前面,后序法是树根在后面,遍历方式都是先左子树后右子树。
一、中序遍历
中序遍历是“左中右”的遍历顺序,也就是从树的左侧逐步向下方移动,直到无法移动,再访问此节点,并向右移动一个节点。如果无法再向右移动,就可以返回上层的父节点,并重复左、中、右的步骤进行。
- 遍历左子树
- 遍历树根
- 遍历右子树
void Inorder(TreeNode* tempTree) {
if (tempTree != nullptr) {
Inorder(tempTree->leftNode);
cout << tempTree->data << " ";
Inorder(tempTree->rightNode);
}
}
二、后序遍历
后序遍历是“左右中”的遍历顺序,即先遍历左子树,再遍历右子树,最后遍历(或访问)根节点,反复执行此步骤。
- 遍历左子树
- 遍历右子树
- 遍历树根
void Postorder(TreeNode* tempTree) {
if (tempTree != nullptr) {
Postorder(tempTree->leftNode);
Postorder(tempTree->rightNode);
cout << tempTree->data << " ";
}
}
三、前序遍历
前序遍历是“中左右”的遍历顺序,也就是先从根节点遍历,再往左方移动,当无法继续时,继续向右方移动,接着重复执行此步骤。
- 遍历树根
- 遍历左子树
- 遍历右子树
void Preorder(TreeNode* tempTree) {
if (tempTree != nullptr) {
cout << tempTree->data << " ";
Preorder(tempTree->leftNode);
Preorder(tempTree->rightNode);
}
}
C++代码
#include<iostream>
using namespace std;
struct TreeNode {
int data;
TreeNode* leftNode;
TreeNode* rightNode;
TreeNode(int tempData, TreeNode* tempLeftNode = nullptr, TreeNode* tempRightNode = nullptr) {
this->data = tempData;
this->leftNode = tempLeftNode;
this->rightNode = tempRightNode;
}
};
class Tree {
private:
TreeNode* treeNode;
public:
Tree() {
treeNode = nullptr;
}
TreeNode* GetTreeNode() {
return this->treeNode;
}
void AddNodeToTree(int* tempData, int tempSize) {
for (int i = 0; i < tempSize; i++) {
TreeNode* currentNode;
TreeNode* newNode;
int flag = 0;
newNode = new TreeNode(tempData[i]);
if (treeNode == nullptr)
treeNode = newNode;
else {
currentNode = treeNode;
while (!flag) {
if (tempData[i] < currentNode->data) {
if (currentNode->leftNode == nullptr) {
currentNode->leftNode = newNode;
flag = 1;
}
else
currentNode = currentNode->leftNode;
}
else {
if (currentNode->rightNode == nullptr) {
currentNode->rightNode = newNode;
flag = 1;
}
else
currentNode = currentNode->rightNode;
}
}
}
}
}
void Preorder(TreeNode* tempTree) {
if (tempTree != nullptr) {
cout << tempTree->data << " ";
Preorder(tempTree->leftNode);
Preorder(tempTree->rightNode);
}
}
void Inorder(TreeNode* tempTree) {
if (tempTree != nullptr) {
Inorder(tempTree->leftNode);
cout << tempTree->data << " ";
Inorder(tempTree->rightNode);
}
}
void Postorder(TreeNode* tempTree) {
if (tempTree != nullptr) {
Postorder(tempTree->leftNode);
Postorder(tempTree->rightNode);
cout << tempTree->data << " ";
}
}
};
int main() {
int data[]{ 7,4,1,5,16,8,11,12,15,9,2 };
cout << "原始数据:" << endl;
for (int i = 0; i < 11; i++)
cout << data[i] << " ";
cout << endl;
Tree* tree = new Tree;
tree->AddNodeToTree(data, 11);
cout << "前序遍历:" << endl;
tree->Preorder(tree->GetTreeNode());
cout << endl;
cout << "中序遍历:" << endl;
tree->Inorder(tree->GetTreeNode());
cout << endl;
cout << "后序遍历:" << endl;
tree->Postorder(tree->GetTreeNode());
cout << endl;
return 0;
}
结果输出