目录
一.二叉树的结构
二.二叉树的操作
1.二叉树的创建
2.二叉树的销毁
3.二叉树的节点个数
4.二叉树叶子节点个数
5.二叉树第K层的节点数
6,二叉树查找
7.前序遍历
8.中序遍历
9.后序遍历
10.层序遍历
11,判断是否是完全二叉树
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
根节点(Root): 二叉树的顶部节点称为根节点,它是树的起始点。
节点(Node): 每个节点包含一个数据元素,同时可能有一个指向左子节点和右子节点的指针。
子节点(Children): 每个节点最多有两个子节点,分别为左子节点和右子节点。
叶子节点(Leaf): 没有子节点的节点称为叶节点,它们位于二叉树的末端。
深度(Depth): 从根节点到某个节点的唯一路径上的节点数称为该节点的深度。根节点的深度为0。
高度(Height): 从某个节点到其最远叶节点的路径上的节点数称为该节点的高度。树的高度即为根节点的高度。
子树(Subtree): 由一个节点及其所有后代节点组成的集合称为子树。
二叉树一般用链式结构构造
BTNode* BuyTreeNode(BTDataType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
if (a[*pi] == '#')
{
(*pi)++;
return NULL;
}
BTNode* newNode = BuyTreeNode(a[*pi]);
(*pi)++;
newNode->left = BinaryTreeCreate(a, pi);
newNode->right = BinaryTreeCreate(a, pi);
return newNode;
}
BuyTreeNode用来创建新节点,BinaryTreeCreate用来创建整个树,并返回根节点,传入数组a和一个用来控制下标的pi,pi初始是0,
void BinaryTreeDestroy(BTNode* root)
{
if (root == NULL);
return;
BinaryTreeDestroy(root->left);
BinaryTreeDestroy(root->right);
free(root);
}
使用后序遍历释放每一个节点
int BinaryTreeSize(BTNode* root)
{
return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}
如果为空返回0.否则返回左子树和右子树的节点和加上根节点
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);
}
如果是叶子节点就返回1,否则返回左子树和右子树的叶子节点之和
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);
}
如果K为1表示当前节点是第K层的节点,返回1,否则返回左子树和右子树的第K-1层的节点数
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
return NULL;
if (root->data == x)
return root;
BTNode* T1 = BinaryTreeFind(root->left, x);
BTNode* T2 = BinaryTreeFind(root->right, x);
if (T1 != NULL)
return T1;
if (T2 != NULL)
return T2;
return NULL;
}
如果当前节点是要查找的,直接返回,不然就向左子树和右子树找,返回找到的节点,找不到返回空
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;
BinaryTreePostOrder(root->left);
BinaryTreePostOrder(root->right);
printf("%c ", root->data);
}
void BinaryTreeLevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
QueuePush(&q, root);
int size = 1;
while (!QueueEmpty(&q))
{
while (size--)
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if(front->left!=NULL)
QueuePush(&q, front->left);
if (front->right != NULL)
QueuePush(&q, front->right);
printf("%c ", front->data);
}
size = QueueSize(&q);
printf("\n");
}
QueueDestroy(&q);
}
利用队列实现层序遍历,先将根节点入队列,每次出队列都会把其非空左右子树的根节点入队列,
int BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
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 != NULL)
{
QueueDestroy(&q);
return 0;
}
}
QueueDestroy(&q);
return 1;
}
当取队头元素为空时,说明所有非空节点已经入队列,这时检查后面是否还有非空节点,如果没有,那就是完全二叉树