二叉树
性质
二叉树是n(n>0)个节点所构成的集合,它或为空树(n=0),或为非空树。对于非空树T:
- 有且仅有一个称之为根的节点;
- 除根节点以外的其余节点分为两个互不相交的子集T1和T2,分别称为T的左子树和右子树,且T1和T2本身又都是二叉树。
二叉树与树的区别
- 二叉树每个节点至多只有两棵子树(二叉树中不存在度大于2的节点);
- 二叉树的子树有左右之分,其次序不能任意颠倒。
- 二叉树的递归定义表明二叉树或为空,或由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。由于这两棵子树也是二叉树,则由二叉树的定义,它们也可以是空树。
分类
满二叉树
如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树。满二叉树除了满足普通二叉树的性质,还具有以下性质:
- 满二叉树中第i层的节点数为2^(n-1)个。
- 深度为k的满二叉树必有2^(k-1) 个节点,叶子数为2^(k-1)。
- 满二叉树中不存在度为1的节点,每一个分支点中都两棵深度相同的子树,且叶子节点都在最底层。
- 4.具有n个节点的满二叉树的深度为log2(n+1)。
完全二叉树
如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树。
二叉查找树
也称二叉搜索树或二叉排序树是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
平衡二叉树
平衡二叉树(AVL树):如果二叉树的所有节点的两棵子树的高度差不大于1,则二叉树被称为平衡二叉树。
遍历
先序遍历
//先序遍历
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
中序遍历
//中序遍历
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
后序遍历
//后序遍历
void PostOrderTraverse(BiTree T)
{
if(T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data;
}
}
代码展示
#include <iostream>
using namespace std;
typedef struct Node
{//定义二叉树结构
char data;
struct Node* lchild, * rchild;
}*BiTree, BiTNode;
void CreateBiTree(BiTree& T)
{//先序创建二叉树
char ch;
cin >> ch;
if (ch == '#') T = NULL;
else {
T = new BiTNode;
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void InOrderTraverse(BiTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
//中序遍历
void InOrderTraverse(BiTree T)
{
if (T)
{
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
//后序遍历
void PostOrderTraverse(BiTree T)
{
if (T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data;
}
}
void tree_destory(BiTNode* root)
{
if (root == NULL)
{
return;
}
//要采用后序遍历,不然父节点销毁了就找不到子节点了
tree_destory(root->lchild);
tree_destory(root->rchild);
free(root);
}