前言
总结一下树的代码。
一、头文件(节点类、树类以及遍历方法的声明)
#pragma once
#include <iostream>
#include <vector>
using namespace std;
//节点类
class TreeNode {
public:
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
//树类
class BTree {
public:
TreeNode* root;
void buildTree(vector<int>& a);
TreeNode* getRoot();
};
//递归遍历二叉树
void firstRoot(TreeNode* node);
void midRoot(TreeNode* node);
void backRoot(TreeNode* node);
//非递归方法遍历二叉树
void firstRootno(TreeNode* node);
void midRootno(TreeNode* node);
void backRootno(TreeNode* node);
//层次遍历(两种方法)
void layerOrder(TreeNode* node);
二、cpp文件
构建二叉搜素树
每个节点的值通过vector数组传入。
void BTree::buildTree(vector<int> &a) {
if (a.size() == 0) {
return;
}
TreeNode* node;
root = new TreeNode(a[0]);
for (int i = 1; i < a.size(); i++) { //第一个元素已经创建过了,所以从第二个元素开始
TreeNode* newNode = new TreeNode(a[i]); //创建新结点
node = root;
while (node) {
if (a[i] < node->val) { //如果小于当前节点的值就去该节点的左子树寻找合适的位置
if (node->left == NULL) { //如果当前节点的左节点为NULL则把新节点作为当前节点的左节点
node->left = newNode;
break; //结束此次循环
}
node = node->left;
}
else { //与上面同理,只不过此次是往右判断
if (node->right == NULL) {
node->right = newNode;
break;
}
node = node->right;
}
}
}
}
递归遍历二叉树
递归遍历总的来说就是四条语句,一条判空,剩下三条根据遍历的次序分别对应不同的顺序。
//前序遍历
void firstRoot(TreeNode* node) {
if (node == NULL) {
return;
}
cout << node->val << endl;
firstRoot(node->left);
firstRoot(node->right);
}
//中序遍历
void midRoot(TreeNode* node) {
if (node != NULL) {
return;
}
midRoot(node->left);
cout << node->val << endl;
midRoot(node->right);
}
//后序遍历
void backRoot(TreeNode* node) {
if (node == NULL) {
return;
}
backRoot(node->left);
backRoot(node->right);
cout << node->val << endl;
return;
}
非递归遍历二叉树
我写的非递归都是用栈来实现的,后序遍历用了两个栈,有用一个栈的方法,但是逻辑比较复杂就没有写。
//前序遍历
void firstRootno(TreeNode* node) {
stack<TreeNode*> stk;
TreeNode* cur;
stk.push(node);
while (!stk.empty()) {
cur = stk.top();
stk.pop();
cout << cur->val << endl;
if (cur->right != NULL) {
stk.push(cur->right);
}
if (cur->left != NULL) {
stk.push(cur->left);
}
}
}
//中序遍历
void midRootno(TreeNode* node) {
stack<TreeNode*> stk;
TreeNode* cur = node;
while (!stk.empty() || cur != NULL) {
while (cur != NULL) {
stk.push(cur);
cur = cur->left;
}
if (!stk.empty()) {
cur = stk.top();
cout << cur->val << endl;
stk.pop();
cur = cur->right;
}
}
}
//后序遍历
void backRootno(TreeNode* node) {
stack<TreeNode*> s1;
stack<TreeNode*> s2;
TreeNode* cur;
s1.push(node);
while (!s1.empty())
{
cur = s1.top();
s1.pop();
s2.push(cur);
if (cur->left != NULL) {
s1.push(cur->left);
}
if (cur->right) {
s1.push(cur->right);
}
}
while (!s2.empty()) {
cur = s2.top();
s2.pop();
cout << cur->val << endl;
}
}
层次遍历遍历
层次遍历用的是队列。用两个遍历分别记录当前这一层的最右边元素和下一层最右边的元素。
void layerOrder(TreeNode* node) {
queue<TreeNode*> que;
TreeNode* cur ;
TreeNode* last = node;
TreeNode* nlast = NULL;
que.push(node);
while (!que.empty()) {
cur = que.front();
que.pop();
cout << cur->val << ' ';
if (cur->left != NULL) {
que.push(cur->left);
nlast = cur->left;
}
if (cur->right != NULL) {
que.push(cur->right);
nlast = cur->right;
}
if (cur == last) {
cout << endl;
last = nlast;
}
}
}