基本内容
- 二叉树的基本概念和遍历方式
- 使用递归创建一个简单的二叉树
- 二叉树使用递归遍历时的调用栈帧
- 实现代码
- 一些基本操作的递归实现
一、一些基本的东西
首先我们要明确,二叉树是一种数据结构,相比于之前的顺序表和链表,二叉树是一种非线性结构,比较特殊,刚开始入门二叉树,我们需要了解二叉树的基本结构框架,知道如何搭建一个简单的二叉树,当然在這篇笔记或者博客里面提到的基本都是递归算法,要知道一些基本的二叉树的操作。
之前我们在学习例如顺序表链表,栈和队列,会涉及到增删查改,但是在二叉树的基本部分我们不会涉及到增删查改,因为二叉树的实际用处不是很大,我们最重要的是需要了解二叉树的基本结构,为以后的搜索树和平衡树的学习打下基础。二叉树的遍历是目前阶段我们需要熟练掌握的内容。
二叉树的遍历方式有三种:前序、中序和后序。 在学习二叉树的时候,把二叉树分为三部分:根结点,左子树和右子树,所谓遍历方式即访问这三部分的先后顺序。
我对于二叉树遍历的方式的理解是這样的:
前序遍历:先访问根结点,再访问左子树,最后访问右子树。
中序遍历:先访问左子树,再访问根节点,最后访问右子树。
后序遍历:先访问左子树,再访问右子树,最后访问根结点。
以一个简单的二叉树为例子
该二叉树一共有六个结点,将6个整数放置其中。
一个结点里面分为三个部分,一个部分存放数据,另外两个存放指向左子树根结点的指针和指向右子树根结点的指针。
二、一些基本的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<assert.h>
#include<stack>
#include<queue>
using namespace std;
template<class T>
struct BinaryTreeNode
{
T _data;
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
BinaryTreeNode(const T& d)
:_data(d)
,_left(NULL)
, _right(NULL)
{
cout << "构造二叉树结点" << endl;
}
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
private:
Node* _root;
protected:
Node* _CreateTree(T* a, size_t n, const T& invalid, size_t& index) //這里的index由调用這个函数的那个函数里面给传进来;但是這里出现了问题,还是因为栈帧的原因,在往根节点回的时候,下层的index并不会影响上层的index从而导致错 误解决方案是: &
{
//index = 0; //注意:這里不能给下标一个初值,递归会出现问题
Node* root = NULL;
if (index < n && a[index] != invalid)
{
root = new Node(a[index]);
root->_left = _CreateTree(a, n, invalid, ++index); //出现的问题: 我一开始写的是index++,但是出现了无限循环,注意创建的新的栈帧就会产生新的index
root->_right = _CreateTree(a, n, invalid, ++index);
}
return root;
}
void _PrevOrder(Node* root) //前序遍历
{
if (root == NULL) //返回条件
return;
cout << root->_data << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
void _InOrder(Node* root) //中序遍历
{
if (root == NULL) //返回条件
return;
_InOrder(root->_left);
cout << root->_data << " ";
_InOrder(root->_right);
}
void _PostOrder(Node* root) //后序遍历
{
if (root == NULL) //返回条件