二叉树的创建
由于在二叉树的创建过程中,我们需要使用输入/读取的值来判定二叉树是否有左节点或者右节点。因此我们在创建的时候就需要使用指针的引用或者二重指针。
我们定义二叉树的基本结点形式如下所示:
typedef int Elemtype;
struct node
{
Elemtype data;
node* lchild;
node* rchild;
};
typedef node* Node;
为了方便理解,我们来捋一遍使用二重指针在创建二叉树时的过程。
首先,我们定义了一个结构体 node
之后,我们有一个指向这个结构体的结构体指针 Node
最后,我们有一个指向这个结构体指针的二重指针 Node*
在我们创建的时候,若二叉树某个结点为空,那我们就令 Node* 指向的那个 Node 为空。而如果 Node 的值是空的,那么自然就没有结构体 node 的地方了,这个结点就相当于没有了。
那么有人可能会问,那我直接令 Node 为空不行吗。答案是不行的,因为你在使用递归法创建二叉树的时候,所改变的参数就是 Node 这个指针,也就是操作 Node 这个指针数据类型和操作其他的 int 等数据类型原理是一样的。如果直接进行传递,就相当于传递了形参,并无法将二叉树联系在一起,反而会造成漫山遍野的野指针。
我们可以简单记,操作什么类型数据,就传递高一级别的指针。
使用指针的引用原理极为简单,我们也可以用这种方法。
二重指针代码
void ini_BTree2(Node* T)
{
string data;
cin >> data;
//结点不存在
if (data == "#")
{
*T = NULL;
}
else
{
*T = new node;
(*T)->data = stoi(data);
ini_BTree((*T)->lchild);
ini_BTree((*T)->rchild);
}
}
指针的引用代码
void ini_BTree(Node &T)
{
string data;
cin >> data;
//结点不存在
if (data == "#")
{
T = NULL;
}
else
{
T = new node;
T->data = stoi(data);
ini_BTree(T->lchild);
ini_BTree(T->rchild);
}
}
二叉树的遍历
一般来讲,二叉树有三种遍历方法,分别是先序中序和后序。
先序算法步骤为:
① 访问根结点;
② 先序遍历根结点的左子树;
③ 先序遍历根结点的右子树;
中序算法步骤为:
① 中序遍历根结点的左子树;
② 访问根结点;
③ 中序遍历根结点的右子树;
后序算法步骤为:
① 后序遍历根结点的左子树;
② 后序遍历根结点的右子树;
③ 访问根结点;
以下面这个二叉树为例,我们来说明一下中序算法的遍历步骤。对于一个简单的二叉树,也就是只有根节点、左儿子右儿子的二叉树(例如图中的ABC),中序遍历的顺序是BAC。在二叉树中,所有的结点都可以认为是简单二叉树的组合,那么这样,我们就可以得到:
HDIBJEAFCG
这样一个中序遍历的二叉树
//先序遍历
void PreOrder(Node T)
{
cout << T->data << endl;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
//中序遍历
void InOrder(Node T)
{
InOrder(T->lchild);
cout << T->data << endl;
InOrder(T->rchild);
}
//后序遍历
void PostOrder(Node T)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
cout << T->data << endl;
}
二叉树结点数量计算
int count(Node T)
{
if (T == NULL)
return 0;
else
return 1 + count(T->lchild) + count(T->rchild);
}