目录
[2. 二叉树链式结构的实现](#2. 二叉树链式结构的实现)
[2.1 创建一棵简单的链式二叉树](#2.1 创建一棵简单的链式二叉树)
[1. 创建节点](#1. 创建节点)
[2. 创建一棵简单的链式二叉树](#2. 创建一棵简单的链式二叉树)
[2.2 二叉树的前、中、后序遍历](#2.2 二叉树的前、中、后序遍历)
[1. 前序遍历](#1. 前序遍历)
[2. 中序遍历](#2. 中序遍历)
[3. 求二叉树节点个数](#3. 求二叉树节点个数)
[3.1 求总节点个数](#3.1 求总节点个数)
[3.2 求叶子节点个数](#3.2 求叶子节点个数)
[3.3 求第K层节点个数](#3.3 求第K层节点个数)
1.二叉树的链式存储结构
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个区域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。
如图:
2. 二叉树链式结构的实现
2.1 创建一棵简单的链式二叉树
注意:相比之下,对普通的链式二叉树进行增删查改其实是非常麻烦的,上篇文章中,我们对堆进行插入和删除的目的是为了找出最大值或最小值,而对于普通的链式二叉树,与其这样漫无目的的进行增删查改,选择顺序表、链表的存储方式反而会更加优雅。所以对于链式二叉树,我们只学习耳熟能详的前序、中序、后序遍历。
1. 创建节点
//创建链式二叉树节点
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;//数据域
struct BinaryTreeNode* _left;//左孩子
struct BinaryTreeNode* _right;//右孩子
}BTNode;
2. 创建一棵简单的链式二叉树
BTNode* BuyNode(int x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
BTNode* CreatBinaryTree()
{
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
node1->left = node2;
node1->right = node4;
node2->left = node3;
node4->left = node5;
node4->right = node6;
return node1;
}
(注意:上述代码并不是创建二叉树的方式,只是为了下面方便遍历二叉树快速生成一棵二叉树)
2.2 二叉树的前、中、后序遍历
二叉树的遍历有:前序/中序/后序的递归结构遍历:
1. 前序遍历(Preorder Traversal 亦称先序遍历)------访问根结点的操作发生在遍历其左右子树之前(根左右) (又称先根遍历-NLR);
2. 中序遍历(Inorder Traversal)------访问根结点的操作发生在遍历其左右子树之中(左根右)(又称中根遍历-LNR);
3. 后序遍历(Postorder Traversal)------访问根结点的操作发生在遍历其左右子树之后(左右根)(又称后根遍历-LRN)。
1. 前序遍历
//前序遍历
void PrevOrder(BTNode* root)
{
if (root == NULL) {
return;
}
printf("%d ", root->data);
PrevOrder(root->left);
PrevOrder(root->right);
}
2. 中序遍历
//中序遍历
void InOrder(BTNode* root)
{
if (root == NULL) {
return;
}
InOrder(root->left);
printf("%d ", root->data);
InOrder(root->right);
}
3.后序遍历
//后序遍历
void PostOrder(BTNode* root)
{
if (root == NULL) {
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->data);
}
3. 求二叉树节点个数
3.1 求总节点个数
//求节点个数
int TreeSize(BTNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
3.2 求叶子节点个数
//求叶子节点个数
int TreeLeafSize(BTNode* root)
{
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
}
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
3.3 求第K层节点个数
//求第K层的节点个数
int TreeKLevel(BTNode* root, int k)
{
assert(k > 0);
if (root == NULL) {
return 0;
}
if (k == 1) {
return 1;
}
return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}
源代码:
#include <stdio.h>
#include <assert.h>
//创建链式二叉树节点
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;//数据域
struct BinaryTreeNode* left;//左孩子
struct BinaryTreeNode* right;//右孩子
}BTNode;
BTNode* BuyNode(int x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
BTNode* CreatBinaryTree()
{
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
node1->left = node2;
node1->right = node4;
node2->left = node3;
node4->left = node5;
node4->right = node6;
return node1;
}
//前序遍历
void PrevOrder(BTNode* root)
{
if (root == NULL) {
return;
}
printf("%d ", root->data);
PrevOrder(root->left);
PrevOrder(root->right);
}
//中序遍历
void InOrder(BTNode* root)
{
if (root == NULL) {
return;
}
InOrder(root->left);
printf("%d ", root->data);
InOrder(root->right);
}
//后序遍历
void PostOrder(BTNode* root)
{
if (root == NULL) {
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->data);
}
//二叉树的销毁
void TreeDestroy(BTNode* root)
{
if (root == NULL) {
return;
}
TreeDestroy(root->left);
TreeDestroy(root->right);
free(root);
root = NULL;
}
//求节点个数
int TreeSize(BTNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
//求叶子节点个数
int TreeLeafSize(BTNode* root)
{
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
}
return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}
//求第K层的节点个数
int TreeKLevel(BTNode* root, int k)
{
assert(k > 0);
if (root == NULL) {
return 0;
}
if (k == 1) {
return 1;
}
return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}
int main()
{
printf("前序遍历为:");
PrevOrder(CreatBinaryTree());
printf("\n前序遍历为:");
InOrder(CreatBinaryTree());
printf("\n后序遍历为:");
PostOrder(CreatBinaryTree());
printf("\n节点个数为:%d",TreeSize(CreatBinaryTree()));
printf("\n叶子节点个数为:%d", TreeLeafSize(CreatBinaryTree()));
printf("\n第%d层节点个数为:%d", 2,TreeKLevel(CreatBinaryTree(),2));
TreeDestroy(CreatBinaryTree());
return 0;
}