二叉树的基本单位和链表一样是以节点为单位
二叉树的节点的存储分为3个部分
1.存放数据 2.存放指向左子树的指针 3.存放指向右子树的指针
typedef char TDateType;
typedef struct BinaryTreeNode
{
TDateType date;
struct BinaryTreeNode *left; //指向左子树的指针
struct BinaryTreeNode *right; //指向右子树的指针
}BTNode;
接下来是二叉树的基本接口
BTNode *BinaryTreeCreate(TDateType *a,int n,int *pi); //二叉树的创建
void BinaryTreeDestory(BTNode* root); //二叉树的销毁
int BinaryTreeSize(BTNode* root); //节点数
int BinaryTreeLeafSize(BTNode* root); //叶节点数
int BinaryTreeLevelKSize(BTNode* root, int k); //第K层的结点数
// 遍历 递归
void BinaryTreePrevOrder(BTNode* root); //前序
void BinaryTreeInOrder(BTNode* root); //中序
void BinaryTreePostOrder(BTNode* root); //后序
void BinaryTreeLevelOrder(BTNode* root); //层序
1.二叉树的创建
BTNode *BuyBTNode(TDateType x)//创建一个节点
{
BTNode *node = (BTNode *)malloc(sizeof(BTNode));
node->left = NULL;
node->right = NULL;
node->date = x;
return node;
}
BTNode *BinaryTreeCreate(TDateType *a,int n,int *pi)
{
if(a[*pi] != '#')
{
BTNode *root = BuyBTNode(a[*pi]);//不为空就创建节点
(*pi)++; //左子树的创建
root->left = BinaryTreeCreate(a,n,pi);
(*pi)++;//右子树的创建
root->right
= BinaryTreeCreate(a,n,pi);
return root;
}
else
{
return NULL;
}
}
二叉树的创建就是先化成子问题然后利用递归的方法完成创建 先创建一个节点然后创建左子树,右子树,然后递归。
2.二叉树的销毁
void BinaryTreeDestory(BTNode* root)
{
if(root != NULL)
{
if(root->left)
{
BinaryTreeDestory(root->left);
root->left = NULL;
}
if(root->right)
{
BinaryTreeDestory(root->right);
root->right = NULL;
}
if(root != NULL)
{
free(root);
root = NULL;
}
}
}
销毁也是递归的思想也是化成子问题但是和创建的顺序不一样 因为如果销毁根节点就无法访问到左子树和右子树了 所以先销毁左子树然后右子树最后销毁根节点,注意最后不要忘记置成空,防止变成野指针。
3.二叉树的节点数计算
int BinaryTreeSize(BTNode* root)
{
if(root == NULL)
{
return 0;
}
return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
同样我们分解成子问题 总结点数等于左子树+右子树+根节点 然后利用递归就可以算出、
4.二叉树的叶节点个数
int BinaryTreeLeafSize(BTNode* root)
{
if(root == NULL)
{
return 0;
}
if(root->left == NULL && root->right == NULL)
{
return 1;
}
return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}
和总节点的计算方法类似 ,区别在于加上限定的条件,每次遇到叶节点返回1 最后将左子树的叶节点和右子树的叶节点相加
5.第K层的节点数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
if(k == 0)
{
return 0;
}
if(k == 1)
{
return 1;
}
return BinaryTreeLevelKSize(root->left,k-1) + BinaryTreeLevelKSize(root->right,k-1);
}
计算第K层的节点数 我们可以看成计算第K-1层的左子树+右子树 然后利用递归解决
6.二叉树的前中后序遍历
void BinaryTreePrevOrder(BTNode* root)//前序
{
if(root == NULL)
{
return ;
}
printf("%c ",root->date);
BinaryTreePrevOrder(root->left);
BinaryTreePrevOrder(root->right);
}
void BinaryTreeInOrder(BTNode* root)//中序
{
if(root == NULL)
{
return ;
}
BinaryTreeInOrder(root->left);
printf("%c ",root->date);
BinaryTreeInOrder(root->right);
}
void BinaryTreePostOrder(BTNode* root)//后序
{
if(root == NULL)
{
return ;
}
BinaryTreePostOrder(root->left);
BinaryTreePostOrder(root->right);
printf("%c ",root->date);
}
前中后序的遍历方法分为递归和非递归 ,这次就先介绍递归的方法
递归的方法同样是化成子问题前中后序遍历的顺序不一样 化成的子问题就不一样
前序:根节点 左子树 右子树
中序:左子树 根节点 右子树
后序:左子树 右子树 根节点
这就是二叉树的建立和基本操作