二叉树(Binary tree)是指计算机科学中每个结点最多有两个子树的树结构,其子树被称作“左子树”(left subtree)和“右子树”(right subtree),常被用于实现二叉查找树和二叉堆。在二叉树中,一个元素也称作一个结点。当集合为空时,称该二叉树为空二叉树。
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
二叉树的特点:
代码如下:
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
代码如下:
BTNode* CreateTreeNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
使用后序遍历先删除左指针和右指针,最后才释放根节点。
代码如下:
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return ;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
这里的递归形式和前序一样,就不再绘图。
代码如下:
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
这里的递归形式和前序一样,就不再绘图。
代码如下:
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
直接左子树节点个数加上右子树节点个数,在加上根节点即可。
代码如下:
int TreeSize(BTNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
用左节点和右节点都为NULL带返回值计算叶子节点个数
代码如下:
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);
}
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);
}
先判断根节点的值,如果不是则从左子树和右子树寻找,都不是则返回NULL。
代码如下:
{
if (root == NULL)
{
return NULL;
}
if (root->data == x)
{
return root;
}
BTNode* Lret = BinaryTreeFind(root->left, x);
if (Lret)
{
return Lret;
}
BTNode* Rret = BinaryTreeFind(root->right, x);
if (Rret)
{
return Rret;
}
return NULL;
}
void BinaryTreeLevelOrder(BTNode* root)
{
struct 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);
}
}
printf("\n");
}
bool BinaryTreeComplete(BTNode* root)
{
struct 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)) //因为上次循环由于碰到NULL退出来,在写层循环如果没有碰到非空,则是完全二叉树,否则不是
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front)
{
return false;
}
}
return true;
}
以上就是今天要讲的内容,本文仅仅简单介绍了树的使用,树提供了大量能使我们快速便捷地处理数据的函数和方法。这里只介绍了普通的树,不过对于我们还是非常重要的,我们好好掌握!另外,如果有需要源码的私信我即可。还有,如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。