1.二叉树的基本操作:
进行基本操作要调用的函数:
#include"BTree.h"
//申请一个节点
BTreeNode *BuyBTreeNode(DataType data)
{
BTreeNode *NewNode = (BTreeNode *)malloc(sizeof(BTreeNode));
if(NULL == NewNode)
{
assert(0);
}
NewNode->data = data;
NewNode->left = NULL;
NewNode->right = NULL;
return NewNode;
}
//构建树
void CreatBTree(BTreeNode **cur, DataType *str, DataType invalid, int *index)
{
BTreeNode *ret = NULL;
assert(cur&&str);
if(str[*index] && invalid != str[*index])
{
(*cur) = BuyBTreeNode(str[*index]);
(*index)++;
CreatBTree(&(*cur)->left, str, invalid , index);
if(str[*index] != '\0')
{
(*index)++;
CreatBTree(&(*cur)->right, str, invalid , index);
}
}
}
//拷贝树
void CpBTree(BTreeNode *cur, BTreeNode **ret)
{
assert(ret);
if(cur)
{
(*ret) = BuyBTreeNode(cur->data);
CpBTree(cur->left, &(*ret)->left);
CpBTree(cur->right, &(*ret)->right);
}
}
//销毁
void Destroy(BTreeNode **cur)
{
BTreeNode *ret = *cur;
assert(cur);
if(*cur)
{
Destroy(&ret->left);
Destroy(&ret->right);
free(ret);
ret = NULL;
}
}
(1)前序遍历:
思路:
递归思路:如果二叉树为空时,算法结束,否则递归循环下面的操作:
a. 遍历根节点。
b. 递归遍历根节点的左子数
c. 递归遍历根节点的右子树
//前序遍历
void Preorder(BTreeNode *cur)
{
if(cur)
{
printf("%c",cur->data);
Preorder(cur->left);
Preorder(cur->right);
}
}
(2)中序遍历
思路:
递归思路:如果二叉树为空时,算法结束,否则递归循环下面的操作:
a. 递归遍历根节点的左子数
b. 遍历根节点。
c. 递归遍历根节点的右子树
//中序
void Inorder(BTreeNode *cur)
{
if(cur)
{
Inorder(cur->left);
printf("%c",cur->data);
Inorder(cur->right);
}
}
(3)后序遍历
思路:
递归思路:如果二叉树为空时,算法结束,否则递归循环下面的操作:
a. 递归遍历根节点的左子数
b. 递归遍历根节点的右子树
c. 遍历根节点。
//后序
void Postorder(BTreeNode *cur)
{
if(cur)
{
Postorder(cur->left);
Postorder(cur->right);
printf("%c",cur->data);
}
}
(4)二叉树节点的个数
思路:左子树和右子树的个数之和然后+1(根节点的个数)
//求树的节点个数
int BTreeNum(BTreeNode *cur)
{
if(cur == NULL)
return 0;
return BTreeNum(cur->left) + BTreeNum(cur->right) + 1;
}
(5)二叉树的高度
思路:如果根节点为空的话,直接返回0.
如果左右子树不为空的话,返回左右子树高度的最大的高度+1(根节点的高度)
//求树的高度
int BTreeHight(BTreeNode *cur)
{
int lefthight = 0;
int righthight = 0;
if(NULL == cur)
return 0;
lefthight = BTreeHight(cur->left);
righthight = BTreeHight(cur->right);
return lefthight > righthight ? lefthight+1 : righthight+1;
}
(6)求二叉树中叶子节点的个数
思路:如果根节点为空的话,直接返回0;
如果二叉树不为空的话,如果根节点的左右子树都为空的话,返回1.
递归遍历左右子树,返回左右子树中的叶子节点之和。
//叶子节点
int BTree(BTreeNode *cur)
{
if(NULL == cur)
return 0;
if(NULL == cur->left && NULL == cur->right)
return 1;
return BTree(cur->left)+BTree(cur->right);
}
(7)求二叉树的第K层的节点个数
思路:如果根节点为空的话,返回0.
如果到达第K层的话,返回1。
然后递归返回左右子树中第K层节点之和。
//求第k层的节点
int BTreeKnum(BTreeNode *cur, int K)
{
if(NULL == cur)
return 0;
if(K == 1)
return 1;
return BTreeKnum(cur->left,K-1) + BTreeKnum(cur->right,K-1);
}
(8)获取一个节点的双亲节点
思路:如果根节点不存在的话,直接返回NULL
如果要求根节点的双亲节点的话,直接返回NULL。
如果根节点的左孩子或者时右孩子是要查找的节点,返回根节点
递归遍历左子树,如果左子树找到双亲节点的话,就不用递归遍历右子树。如果左子树没有找到双亲节点的话,就递归遍历右子树。
//求一个节点的双亲节点
BTreeNode* ParentNode(BTreeNode *cur, DataType data)
{
BTreeNode *ret = NULL;
if(cur == NULL)
return NULL;
if(cur->data == data)
return NULL;
if(cur->left->data == data|| cur->right->data == data)
return cur;
ret = ParentNode(cur->left, data);
//如果左子数找到的话,就不用进右子树找了
//如果左子数找不到的话,进入右子树找
if(ret == NULL)
ret = ParentNode(cur->right, data);
return ret;
}
(9)获取一个节点的左孩子
思路:如果根节点不存在的话,直接返回NULL
如果根节点是你要查找到的节点,直接返回根节点的左孩子。
递归遍历左子树,如果左子树找到的话,就不用递归遍历右子树。如果左子树没有找到的话,就递归遍历右子树。
//求一个节点的左孩子
BTreeNode *LeftNode(BTreeNode *cur, DataType data)
{
BTreeNode *ret = NULL;
if(NULL == cur)
return NULL;
if(cur->data == data)
{
return cur->left;
}
ret = LeftNode(cur->left, data);
//如果左子数找到的话,就不用进右子树找了
//如果左子数找不到的话,进入右子树找
if(ret == NULL)
ret = LeftNode(cur->right, data)