二叉树结构体定义以及函数声明:
typedef int BTDataType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
BTDataType _data;
}BTNode;
BTNode* BuyBTNode(BTDataType x);//创建树的节点
// 创建二叉树
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid);
void BTreePrevOrder(BTNode* root);//先序遍历
void BTreeInOrder(BTNode* root);//中序遍历
void BTreePostOrder(BTNode* root);//后序遍历
size_t BTreeSize(BTNode* root);//树的节点个数
size_t BTreeLeafSize(BTNode* root);//叶节点个数
size_t BTreeKLevelSize(BTNode* root, size_t k);//第k层节点个数
size_t BTreeDepth(BTNode* root);//深度
BTNode* BTreeFind(BTNode* root, BTDataType x);//查找
创建树的节点:
BTNode* BuyBTNode(BTDataType x)
{
BTNode* newNode = (BTNode*)malloc(sizeof(BTNode));
if (newNode == NULL)
return NULL;
newNode->_data = x;
newNode->_left = NULL;
newNode->_right = NULL;
return newNode;
}
创建树:
创建树的时候我们可以先将树节点的数据存放到一个数组里,然后分别将数组的数据存放到树结构中。列如:int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' },“#”井号表示该节点为空。
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid)
{
assert(a);
if (a[*pIndex]!=invalid)
{
BTNode* root = BuyBTNode(a[*pIndex]);
(*pIndex)++;
root->_left = CreateBTree(a, pIndex, invalid);
(*pIndex)++;
root->_right = CreateBTree(a, pIndex, invalid);
return root;
}
return NULL;
}
创建树的时候采用先序遍历的顺序,第一个参数为数组。第二个参数为数组下标,这里需要注意,下标应该传的是指针,因为创建树使用递归来实现的,若传的不是指针而是整型,当在递归调用的过程中返回之前的调用时,下标值会返回之前的数值,与预期不符。第三个参数则是一个标识符,用于判断当前节点是否为空。
先序遍历:
void BTreePrevOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
printf("%d ", root->_data);
BTreePrevOrder(root->_left);
BTreePrevOrder(root->_right);
}
}
如果当前节点为空,则返回。若果不为空,则输出当前节点,然后遍历左孩子,再遍历右孩子。
中序遍历:
void BTreeInOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
BTreeInOrder(root->_left);
printf("%d ", root->_data);
BTreeInOrder(root->_right);
}
}
如果当前节点为空,则返回。若果不为空,则遍历左孩子,然后输出当前节点,再遍历右孩子。
后序遍历:
void BTreePostOrder(BTNode* root)
{
if (root == NULL)
return;
else
{
BTreePostOrder(root->_left);
BTreePostOrder(root->_right);
printf("%d ", root->_data);
}
}
如果当前节点为空,则返回。若果不为空,则遍历左孩子,再遍历右孩子,然后输出当前节点。
树的节点个数:
size_t BTreeSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
else
{
return BTreeSize(root->_left) + BTreeSize(root->_right) + 1;
}
}
叶子节点的个数:
size_t BTreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
if (root->_left == NULL&&root->_right == NULL)
{
return 1;
}
return BTreeSize(root->_left) + BTreeSize(root->_right);
}
第k层节点个数:
size_t BTreeKLevelSize(BTNode* root, size_t k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
else
{
k--;
return BTreeKLevelSize(root->_left, k) + BTreeKLevelSize(root->_right, k);
}
}
树的深度:
size_t BTreeDepth(BTNode* root)
{
int left;
int right;
if (root == NULL)
{
return 0;
}
if (root->_left == NULL&&root->_right == NULL)
{
return 1;
}
else
{
left = BTreeDepth(root->_left) + 1;
right = BTreeDepth(root->_right) + 1;
return left > right ? left : right;
}
}
如果当前节点为空则返回0,若当前节点的左右孩子都为空则返回1,如果上述两种情况都不满足则继续遍历左右孩子,最后返回较大的一个。
查找指定节点:
BTNode* BTreeFind(BTNode* root, BTDataType x)
{
BTNode* res = NULL;
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
if (root->_left != NULL)
{
res = BTreeFind(root->_left, x);
if (res->_data == x)
return res;
}
if (root->_right != NULL)
{
res = BTreeFind(root->_right, x);
if (res->_data == x)
return res;
}
}