一. 初识二叉树
1.1 树的定义
树是一种递归的数据结构,作为一种逻辑结构,同时也是一种分层结构,具有以下两个特点
- 树的根结点没有前驱,除根结点外的所有结点有且只有一个前驱
- 树中所有结点可以有零个或多个后继
树中一个结点的孩子个数称为该结点的度
树的高度(或深度)是树中结点的最大层数
- 结点的深度是从根节点开始自顶向下逐层累加的
- 结点的高度是从叶节点开始自底向上逐层累加的
1.2 二叉树
二叉树是一种树形结构,其特点是每个结点至多只有两颗子树,并且二叉树的子树有左右之分,其次序不能任意颠倒
1.3 满二叉树
如果一棵二叉树只有度为 0 的结点和度为 2 的结点,并且度为 0 的结点在同一层上,则这棵二叉树为满二叉树
可以对满二叉树按层序编号:约定编号从根结点(根结点编号为 1),自上而下,自左向右。这样,每个结点对应一个编号,对于编号为 i 的结点,若有双亲,则其双亲为 “向下取整(i / 2)",若有左孩子,则左孩子为 2i;若有右孩子,则右孩子为 2i+1
1.4 完全二叉树
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点
1.5 二叉树的顺序存储结构
可以使用数组来存储二叉树,从索引 1 开始存储,对孩子结点和父节点的访问参考满二叉树的按层序编号
1.6 二叉树的链式存储结构
在二叉树中,链表结点至少包含 3 个域:数据域 data、左指针域 lchild、右指针域 rchild
class TreeNode{
public:
int data;
TreeNode *lchild;
TreeNode *rchild;
public:
explicit TreeNode(int data, TreeNode *lchild = nullptr, TreeNode *rchild = nullptr)
:data(data), lchild(lchild), rchild(rchild){}
};
1.7由顺序存储转化为链式存储
class Tree{
private:
TreeNode *root;
std::vector<TreeNode *> tree_nodes;
public:
Tree()
:root(nullptr){}
Tree(const std::vector<int> &data, const std::vector<int> &index){
this->tree_nodes.emplace_back(nullptr);
int j = 0;
for(int i = 1; i < index.size(); ++i){
TreeNode *tree_node = nullptr;
if(index[i] == 1)
tree_node = new TreeNode(data[j++]);
this->tree_nodes.emplace_back(tree_node);
if(i == 1)
this->root = tree_node;
}
for(int i = 1; i * 2 < index.size(); ++i){
if(this->tree_nodes[i] != nullptr){
this->tree_nodes[i]->lchild = this->tree_nodes[2 * i];
if(i * 2 + 1 < index.size())
this->tree_nodes[i]->rchild = this->tree_nodes[2 * i + 1];
}
}
}
~Tree(){
for(int i = 1; i < this->tree_nodes.size(); ++i){
if(this->tree_nodes[i] != nullptr)
delete this->tree_nodes[i];
}
}
Tree(const Tree &) = delete;
Tree &operator=(const Tree &) = delete;
public:
TreeNode *getRoot(void) const{
return this->root;
}
void show(void) const{
auto inner = [](const auto &func, TreeNode *root, int depth = 1) -> void{
if(root != nullptr){
printf("%s%d\n", std::string(depth, '-').c_str(), root->data);
func(func, root->lchild, depth+3);
func(func, root->rchild, depth+3);
}else
printf("%s%s\n", std::string(depth, '-').c_str(), "NULL");
};
inner(inner, this->root);
}
};
int main(void){
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7};
std::vector<int> index = {0, 1, 1, 1, 1, 1, 1, 1};
Tree tree(data, index);
tree.show();
return 0;
}