一、基本结构
定义:
//树结点
typedef struct Node
{
int data;
Node* left;
Node* right;
}Node,*Tree;
其中,data为其数据域,
left和right分别为其左孩子指针和右孩子指针。
别名:Node
指针别名:Tree
二、二叉树的建立
假设我们要建立一颗这样的树:
那么直接用代码实现是这样的:
Node* n1 = (Node*)malloc(sizeof(Node));
Node* n2 = (Node*)malloc(sizeof(Node));
Node* n3 = (Node*)malloc(sizeof(Node));
n1->data = 5;
n1->left = n2;
n1->right = n3;
n2->data = 6;
n2->left = NULL;
n2->right = NULL;
n3->data = 7;
n3->left = NULL;
n3->right = NULL;
很繁琐。
但其实我们可以用递归来实现二叉树的建立,封装成一个函数即可:
//二叉树建立
Tree createBinaryTree()
{
Node* n;
n = (Node*)malloc(sizeof(Node));
int Value;
cin >> Value;
if (Value == -1)
{
free(n);
n = NULL;
return NULL;
}
else
{
n->data = Value;
n->left = createBinaryTree();
n->right = createBinaryTree();
return n;
}
}
首先,这个函数的返回值是一个结点指针,所以我们也需要一个结点指针来接收它。
先创建一个空结点,并为其在堆区开辟空间。
然后输入值,这里通过值是否为-1来判断该结点是否生成。
如果是-1,那么首先释放这个结点,制为空,
然后返回一个NULL,结束本次结点赋值。
如果不为-1,那么:
先将值赋给本结点,
然后依次对其左、右结点进行赋值操作。
通过递归的方式,最终返回第一个结点,也就是根,即可。
这样创建二叉树,在main函数里只需要一行代码:
Tree t = createBinaryTree();
三、二叉树的三大遍历
前序遍历:
顺序:根 左 右
//前序遍历
void preOrder(Tree n)
{
if (n != NULL)
{
cout << n->data << " ";
preOrder(n->left);
preOrder(n->right);
}
}
中序遍历:
顺序:左 根 右
//中序遍历
void inOrder(Tree n)
{
if (n != NULL)
{
preOrder(n->left);
cout << n->data << " ";
preOrder(n->right);
}
}
后序遍历:
顺序:左 右 根
//后序遍历
void postOrder(Tree n)
{
if (n != NULL)
{
preOrder(n->left);
preOrder(n->right);
cout << n->data << " ";
}
}
四、二叉树的销毁
既然要销毁二叉树,就意味着每一个结点都需要被释放。
那么显然根节点是最后一个释放的。
因为如果在左右子树还未均释放完毕,就释放根节点,
就会造成断链,结果是部分子树无法释放干净。
所以这里的递归顺序是:左 右 根
void releaseTree(Tree t)
{
if (t != NULL)
{
releaseTree(t->left);
releaseTree(t->right);
free(t);
t = NULL;
}
}
五、演示
同样以这棵树为例:
Tree t = createBinaryTree();
cout << "前序遍历:";
preOrder(t);
cout << endl;
cout << "中序遍历:";
inOrder(t);
cout << endl;
cout << "后序遍历:";
postOrder(t);
cout << endl;
releaseTree(t);
运行截图: