目录
链式二叉树的结构体
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
链式二叉树的创建
如通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树,其中‘#’表示该节点为空。本文采用前序遍历,递归的方式建立一颗链式二叉树。
BTNode* BuyBTNode(BTDataType x) {
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->_data = x;
node->_left = NULL;
node->_right = NULL;
return node;
}
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a,int* pi) {
if (a[*pi] == '#') {
(*pi)++;
return NULL;
}
BTNode* root = BuyBTNode(a[(*pi)++]);
root->_left = BinaryTreeCreate(a, pi);
root->_right = BinaryTreeCreate(a, pi);
return root;
}
该数组建立的二叉树如图所示。要注意的是i作为数组下标,传参要是它的地址,因为在递归的过程中,i的下标每建立一个结点都要往后移。二叉树构建过程如下图所示(只画出部分构建过程,剩下部分以此类推)
二叉树的前、中、后序遍历的实现(递归)
前序遍历
void BinaryTreePrevOrder(BTNode* root) {
if (root == NULL)
return;
printf("%c", root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
前序遍历的递归过程如图所示
中序遍历和后序遍历以此类推。
中序遍历
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root) {
if (root == NULL)
return;
BinaryTreeInOrder(root->_left);
printf("%c", root->_data);
BinaryTreeInOrder(root->_right);
}
后序遍历
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root) {
if (root == NULL)
return;
BinaryTreeInOrder(root->_left);
BinaryTreeInOrder(root->_right);
printf("%c", root->_data);
}
二叉树非空结点的数量
int BinaryTreeSize(BTNode* root) {
return root == NULL ? 0 : 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
}
非空结点计数递归过程如图所示
二叉树叶子结点的数量
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root) {
if (root == NULL) {
return 0;
}
if (root->_left == NULL && root->_right == NULL) {
return 1;
}
else {
return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}
}
叶子结点的递归过程如图所示
二叉树第K层非空节点的数量
// 二叉树第k层节点个数(转化为子树的k-1层的结点)
//如求第三层的节点数,就是求根节点左子树的第二层
int BinaryTreeLevelKSize(BTNode* root, int k) {
assert(k >= 1);
if (root == NULL) {
return 0;
}
if (k == 1)
return 1;
return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
}
假设K==3,求二叉树第三层的非空结点数量
二叉树最大深度
//求二叉树的最大深度
int MaxBinaryTreeDepth(BTNode* root) {
if (root == NULL)
return 0;
int left = MaxBinaryTreeDepth(root->_left) + 1;
int right = MaxBinaryTreeDepth(root->_right) + 1;
return left > right ? left : right;
}
求二叉树最大深度的递归过程如图所示
二叉树的层序遍历
用队列的结构层序遍历,队列的数据类型是二叉树结点的结构指针类型,所以队列存储的是二叉树结点的地址。先进双亲结点,判断队列是否为空,非空,取出队头数据,并删除,将该结点的非空孩子结点进入队列。循环下去,直到队列为空。
typedef BTNode* QDataType;
// 链式结构:表示队列
typedef struct QListNode
{
struct QListNode* _next;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode* _rear;
}Queue;
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root) {
Queue q;
QueueInit(&q);
if (root == NULL) {
return;
}
QueuePush(&q, root);
while (QueueEmpty(&q) == 0) {
BTNode* front = QueueFront(&q);
printf("%c ", front->_data);
QueuePop(&q);
if (front->_left) {
QueuePush(&q, front->_left);
}
if (front->_right) {
QueuePush(&q, front->_right);
}
}
printf("\n");
QueueDestroy(&q);
return;
}
判断二叉树是否为完全二叉树
运用队列来判断一颗二叉树是否为完全二叉树。先将非空的结点入队,判断队列是否为空,非空,取出队头数据,并删除,如果该结点非空,将该节点的孩子入队,循环下去。当队头数据为空时,中断循环,再依次取出队头数据,如果队列后面的数据出现非空结点,则该二叉数不是完全二叉树。完全二叉树在队列遇到空节点时,队列非空取出的结点都是空节点。
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root) {
Queue q;
QueueInit(&q);
if (root == NULL) {
return 0;
}
QueuePush(&q, root);
while (QueueEmpty(&q) == 0) {
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front) {
QueuePush(&q, front->_left);
QueuePush(&q, front->_right);
}
else {
break;//队头遇到空指针中断循环
}
}
while (QueueEmpty(&q) == 0) {
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front) {
QueueDestroy(&q);
return 0;
}
}
QueueDestroy(&q);
return 1;
}