在看到数据结构二叉树部分时,想利用C++实现二叉树的建立与遍历操作,在参考部分网上代码后,自己进行了总结,直接贴代码:
首先要实现一个二叉树类,主要操作有三:1.创建二叉链表节点结构体 2.前序建立二叉树 3.三种遍历操作。
class BiTree
{
public:
BiTree()
{
root = new BiTreeNode(-1,nullptr,nullptr);
}
struct BiTreeNode
{
int val;
BiTreeNode *lchild;
BiTreeNode *rchild;
BiTreeNode(int val):val(val),lchild(nullptr),rchild(nullptr) {}
BiTreeNode(int val, BiTreeNode *lchild, BiTreeNode *rchild) :val(val), lchild(lchild), rchild(rchild) {}
};
void Create_BiTree(vector<int> &nums,int index)
{
root = make_Tree(nums,index);
}
BiTreeNode* make_Tree(vector<int> &nums, int &index)
{
BiTreeNode *T = NULL;
if (index < nums.size() && nums[index] != -1)
{
T = new BiTreeNode(-1);
T->val = nums[index];
T->lchild = make_Tree(nums,++index);
T->rchild = make_Tree(nums,++index);
}
return T;
}
void _PrevOrOrder(BiTreeNode *_root)
{
BiTreeNode *temp = _root;
if (temp == nullptr) return;
cout << temp->val << " ";
_PrevOrOrder(temp->lchild);
_PrevOrOrder(temp->rchild);
}
void _InOrder(BiTreeNode *_root)
{
BiTreeNode *temp = _root;
if (temp == nullptr) return;
_InOrder(temp->lchild);
cout << temp->val << " ";
_InOrder(temp->rchild);
}
void _PostOrder(BiTreeNode* _root)
{
BiTreeNode *temp = _root;
if (temp == nullptr) return;
_PostOrder(temp->lchild);
_PostOrder(temp->rchild);
cout<<temp->val<<" ";
}
BiTreeNode* Get_root()
{
return root;
}
private:
BiTreeNode *root;
};
最后需要添加一个实例进行测试。如下图,紫色部分为实际需要建立的二叉树,但是在写程序时,必须要添加红色部分的节点。我们规定当递归到-1时(红色部分),说明此时已经到头了,这个地方是个NULL,必须要进行回溯了。那么,你可能很奇怪为什么左子树叶子节点需要添加-1,右子树叶子加点不需要,难道右子树不需要知道何时停止递归进行回溯吗?当然不是啦,我们可以发现在make_Tree()函数中有个判断条件(index < nums.size())这其实就是在告诉右子树何时停止递归,索引超过数组当然不行了。
我们现在再次分析下,对于下图这样的二叉树(紫色部分),其前序遍历结果为{1,2,3,4,5,6},我们如果要实现按照前序遍历结果进行二叉树建立,那么一个数组必须定义为{1,2,3,-1,-1,4,-1,-1,5,6},其中四个-1就是下图所注红色填充部分。
我们现在考虑一个问题,还是按照前序遍历建立二叉树,如果4(表示为5的左孩子)现在变为5的右孩子,那么传入的数组还是上面那个吗?直觉告诉我们这样是不对的。在那种情况下,一个数组{1,2,3,-1,-1,4,-1,-1,5,-1,6}需要被建立,多了一个-1。因为按照前序遍历要求,5后面下一个遍历的就是左孩子,虽然我们都知道这个不存在的左孩子就是NULL,但是我们仍然需要将其在数组里表示为-1,这样程序才知道此时需要停止遍历。所以说,传入数组的形式与按照什么次序建立二叉树有很大联系!!!!
这里有个技巧,你在进行遍历时就将所有的NULL都表示出来,比如本例的{1,2,3,NULL,NULL,4,NULL,NULL,5,6,NULL,NULL,NULL,NULL,NULL},最后一个数字后面所有的NULL全部去除(通过判断索引即可),数组内部的NULL变为-1。
#include <iostream>
#include <vector>
class BiTree
{
.........
}
int main()
{
vector<int> v = {1,2,3,-1,-1,4,-1,-1,5,6};
BiTree mytree;
mytree.Create_BiTree(v,0);
mytree._PrevOrOrder(mytree.Get_root());
cout << endl;
mytree._InOrder(mytree.Get_root());
cout << endl;
mytree._PostOrder(mytree.Get_root());
system("pause");
return 0;
}
打印结果:
|