1.链式存储二叉树
用链表来表示一颗二叉树,即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。
前序遍历:根结点、左子树、右子树
中序遍历:左子树、根结点、右子树
后序遍历:左子树、右子树、根结点
2.代码实现
Tree.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//定义二叉树的链式结构
//二叉树结点的结构
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//前序遍历
void PreOrder(BTNode* root);
//中序遍历
void InOrder(BTNode* root);
//后序遍历
void PostOrder(BTNode* root);
//二叉树结点个数
void BinaryTreeSize(BTNode* root, int* psize);
int BinaryTreeSize_1(BTNode* root);
//求叶子结点个数
int BinaryTreeLeafSize(BTNode* root);
//二叉树第k层结点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
//二叉树的深度/高度
int BinaryTreeDepth(BTNode* root);
//二叉树中查找值为x的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
//二叉树销毁
void BinaryTreeDestroy(BTNode** root);
//层序遍历
void LevelOrder(BTNode* root);//队列
//判断二叉树是否为完全二叉树
bool BinaryTreeComplete(BTNode* root);
Tree.c
#include "Tree.h"
#include "Queue.h"
void PreOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
printf("%d ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
void InOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
InOrder(root->left);
printf("%d ", root->data);
PreOrder(root->right);
}
void PostOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->data);
}
void BinaryTreeSize(BTNode* root,int* psize)
{
if (root == NULL)
{
return 0;
}
++*psize;
BinaryTreeSize(root->left,psize);
BinaryTreeSize(root->right,psize);
}
int BinaryTreeSize_1(BTNode* root)
{
if (root == NULL)
{
return 0;
}
return 1 + BinaryTreeSize_1(root->left) + BinaryTreeSize_1(root->right);
}
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);
}
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);
}
int BinaryTreeDepth(BTNode* root)
{
if (root == NULL)
{
return 0;
}
int leftDep = BinaryTreeDepth(root->left);
int rightDep = BinaryTreeDepth(root->right);
return leftDep > rightDep ? leftDep + 1 : rightDep + 1;
}
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if (root == NULL)
{
return 0;
}
if (root->data == x)
{
return root;
}
BTNode* leftFind = BinaryTreeFind(root->left, x);
if (leftFind)
{
return leftFind;
}
BTNode* rightFind = BinaryTreeFind(root->left, x);
if (rightFind)
{
return rightFind;
}
return NULL;
}
void BinaryTreeDestroy(BTNode** root)
{
if (*root == NULL)
{
return 0;
}
BinaryTreeDestroy(&(*root)->left);
BinaryTreeDestroy(&(*root)->right);
free(*root);
*root = NULL;
}
void LevelOrder(BTNode* root)
{
Queue q;
QueueInit(&q);
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
//取队头,打印
BTNode* front = QueueFront(&q);
printf("%d ", front->data);
QueuePop(&q);
//队头的左右孩子入队列
if (front->left)
{
QueuePush(&q,front->left);
}
if (front->right)
{
QueuePush(&q, front->right);
}
}
QueueDestroy(&q);
}
bool 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 false;
}
}
QueueDestroy(&q);
return true;
}