接上篇内容,在本文中,我们将探讨二叉树的前序、中序、后序遍历,节点个数、叶子节点个数、第k层节点个数、查找值为x的节点、判断是否为完全二叉树、深度计算、层序遍历以及二叉树的销毁。下面,我将给出各个操作的C语言实现。
首先,我们需要定义一个二叉树节点的结构体。
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
BTNode* BuyNode(char x)
{
BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
if (newnode == NULL)
{
perror("malloc fail");
return NULL;
}
newnode->_data = x;
newnode->_left = NULL;
newnode->_right = NULL;
return newnode;
}
// 通过前序遍历的数组"A B D # # E # H # # C F # # G # # "构建二叉树
BTNode* BinaryTreeCreate()
{
BTNode* nodeA = BuyNode('A');
BTNode* nodeB = BuyNode('B');
BTNode* nodeC = BuyNode('C');
BTNode* nodeD = BuyNode('D');
BTNode* nodeE = BuyNode('E');
BTNode* nodeF = BuyNode('F');
BTNode* nodeG = BuyNode('G');
BTNode* nodeH = BuyNode('H');
nodeA->_left = nodeB;
nodeB->_right = nodeE;
nodeB->_left = nodeD;
nodeA->_right = nodeC;
nodeE->_right = nodeH;
nodeC->_left = nodeF;
nodeC->_right = nodeG;
return nodeA;
}
前序遍历的顺序是:根节点 -> 左子树 -> 右子树。
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("%c ", 'N');
return;
}
printf("%c ", root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
中序遍历的顺序是:左子树 -> 根节点 -> 右子树。
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if (root == NULL)
{
printf("%c ", 'N');
return;
}
BinaryTreeInOrder(root->_left);
printf("%c ", root->_data);
BinaryTreeInOrder(root->_right);
}
后序遍历的顺序是:左子树 -> 右子树 -> 根节点。
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if (root == NULL)
{
printf("%c ", 'N');
return;
}
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
printf("%c ", root->_data);
}
递归计算二叉树的节点个数。
// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
return root == NULL ? 0 :
BinaryTreeSize(root->_left) +
BinaryTreeSize(root->_right) + 1;
}
递归计算二叉树的叶子节点个数。
// 二叉树叶子节点个数
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);
}
使用队列实现层序遍历,并计算第k层的节点个数。
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
if (root == NULL)
return 0;
if (k == 1)
{
return 1;
}
//子问题
return BinaryTreeLevelKSize(root->_left, k - 1) +
BinaryTreeLevelKSize(root->_right, k - 1);
}
递归查找值为x的节点。
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
BTNode* ret1 = BinaryTreeFind(root->_left, x);
if (ret1)
return ret1;
BTNode* ret2 = BinaryTreeFind(root->_right, x);
if (ret2)
return ret2;
return NULL;
}
完全二叉树的定义是:除了最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干节点。要用到队列内容(可查往期内容).
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
//遇到第一个空,就可以判断,如果队列中还有非空
//就不是完全二叉树;
if (front == NULL)
break;
QueuePush(&q, front->_left);
QueuePush(&q, front->_right);
}
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
//如果有非空 就不是完全二叉树
if (front)
{
QueueDestroy(&q);
return false;
}
}
QueueDestroy(&q);
return true;
}
为(A B C D E F G H)广度优先遍历(BFS),要用到队列内容(可查往期内容).
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
printf("%c ", front->_data);
if (front->_left)
QueuePush(&q, front->_left);
if (front->_right)
QueuePush(&q, front->_right);
}
QueueDestroy(&q);
}
二叉树的最大高度
// 二叉树深度
int BinaryTreeweight(BTNode* root)
{
if (root == NULL)
return 0;
int letfHeight = BinaryTreeweight(root->_left);
int rightHeight = BinaryTreeweight(root->_right);
return letfHeight > rightHeight ?
letfHeight + 1 : rightHeight + 1;
}
// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
return;
BinaryTreeDestory(root->_left);
BinaryTreeDestory(root->_right);
free(root);
}
主函数如下
int main()
{
BTNode* root = BinaryTreeCreate();
int x = 3;
BinaryTreePrevOrder(root);
puts("");
BinaryTreeInOrder(root);
puts("");
BinaryTreePostOrder(root);
puts("");
printf("TreeSize:%d\n",BinaryTreeSize(root));
printf("TreeLeafSize:%d\n", BinaryTreeLeafSize(root));
printf("TreeSizeHeight:%d\n", BinaryTreeweight(root));
printf("BinaryTreeLevelKSize:%d\n", BinaryTreeLevelKSize(root, x));
BTNode* zi = BinaryTreeFind(root, 'H');
printf("%c\n", zi->_data);
bool sa = BinaryTreeComplete;
printf("TreeComplete:%d\n", sa);
BinaryTreeLevelOrder(root);
BinaryTreeDestory(root);
return 0;
}
结果如下