目录
测试用例树的结构
BTNode* n1 = BuyBTNode(1);
BTNode* n2 = BuyBTNode(2);
BTNode* n3 = BuyBTNode(3);
BTNode* n4 = BuyBTNode(4);
BTNode* n5 = BuyBTNode(5);
BTNode* n6 = BuyBTNode(6);
BTNode* n7 = BuyBTNode(7);
n1->left = n2;
n1->right = n3;
n2->left = n4;
n3->left=n5;
n3->right=n6;
n5->left = n7;
0.二叉树结构定义
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType val;
struct BinaryTreeNode*left;
struct BinaryTreeNode*right;
}BTNode;
1.结点的创建
//树结点建立
BTNode*BuyBTNode(BTDataType x)
{
BTNode*p=(BTNode*)malloc(sizeof(BTNode));
if(p==NULL)
{
perror("malloc fail");
return NULL;
}
p->val=x;
p->left=p->right=NULL;
return p;
}
2函数实现
2.1前序遍历
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root)
{
if(root==NULL) return;
printf("%d ",root->val);
BinaryTreePrevOrder(root->left);
BinaryTreePrevOrder(root->right);
}
2.2中序遍历
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
if(root==NULL) return;
BinaryTreeInOrder(root->left);
printf("%d ",root->val);
BinaryTreeInOrder(root->right);
}
2.3后序遍历
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
if(root==NULL) return;
BinaryTreePostOrder(root->left);
BinaryTreePostOrder(root->right);
printf("%d ",root->val);
}
2.4层序遍历
关于层序遍历我们可以用队列和数组实现,但本质上还是一样的。区别在于数组是在所有结点存入后一次性输出。
//队列
void QueueBinaryTreeLevelOrder(BTNode* root)
{
Queue q;//构建栈
QueueInit(&q);//初始化栈
QueuePush(&q,root);//根结点入栈
while(!QueueEmpty(&q))//栈不为空循环
{
BTNode*p=QueueFront(&q);//记录头节点
QueuePop(&q);//出栈
printf("%d ",p->val);
if(p->left) QueuePush(&q,p->left);//左孩子存在入栈
if(p->right) QueuePush(&q,p->right);//右孩子存在入栈
}
}
3.计算二叉树节点个数
int BinaryTreeSize(BTNode* root)
{
if(root==NULL) return 0;
return BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1;
}
4.计算二叉树叶子节点个数
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{
if(root==NULL) return 0;
if(root->left==NULL&&root->right==NULL) return 1;
int l=BinaryTreeLeafSize(root->left);
int r=BinaryTreeLeafSize(root->right);
return l+r;
}
5.二叉树的深度
我们可以用递归来求二叉树的深度,求二叉树的深度相当于从根的左子树和右子树中返回最大的深度然后加1求出,求根左子树的深度同样可以这样来求。
//二叉树深度
int BinaryTreeDeep(BTNode* root)
{
if(root==NULL) return 0;
int left=BinaryTreeDeep(root->left);//左子树的深度
int right=BinaryTreeDeep(root->right);//右子树的深度
return left>right?left+1:right+1;//返回最大深度+1
}
我们也可以采用非递归的方式,我们可以借用数组或者队列来解决,原理也是一样的。我们可以层序遍历二叉树,每遍历一层深度就加1。
//非递归
int QueueBinaryTreeDeep(BTNode* root)
{
BTNode*a[100]={0};
int front=0,rear=0,depth=0,level=0;//front指向该层的第一个结点,rear指向最后一个结点的后面 (下一层的第一个)
if(root) a[rear++]=root;//root不为空入数组
level=rear;//level同样指向该层最后一个结点的后面 (下一层的第一个)
while(front<rear)
{
if(a[front]->left) a[rear++]=a[front]->left;//左孩子存在入数组
if(a[front]->right) a[rear++]=a[front]->right;//右孩子存在入数组
front++;//遍历该层下一个结点
if(front==level)//此时该层已遍历结束 进入下一层
{
depth++;
level=rear;
}
}
return depth;
}
6.二叉树查找值为x的节点
我们可以采用前序遍历的方式来查找x
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
if(root==NULL) return NULL;
if(root->val==x) return root;
BTNode*left=BinaryTreeFind(root->left,x);//遍历左子树找 找到一层一层返回
if(left) return left;
BTNode*right=BinaryTreeFind(root->right,x);
if(right) return right;
return NULL;
}
7.计算二叉树第k层节点个数
求第k层的结点个数,可以分为左子树第k层结点的个数+右子树第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);
}
8.判断二叉树是否是完全二叉树
我们同样可以采用层序遍历的方式来解决,因为非完全二叉树一层中第一个结点到最后一个结点中间会有空结点。
//判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
QueuePush(&q,root);
while(!QueueEmpty(&q))//队不为空循环
{
BTNode*p=QueueFront(&q);//取队首元素
if(p==NULL)
{
if(!QueueEmpty(&q)) return 0;//队首元素为空 但队不为空说明不是完全二叉树
}
QueuePop(&q);
QueuePush(&q,p->left);//左孩子是否为空都入队
QueuePush(&q,p->right);
}
return 1;
}
9.二叉树销毁
// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
if(root==NULL) return;
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
root->val=0;
root->left=NULL;
root->right=NULL;
free(root);
}
小白第一次写博客,关于目录确实不知道怎么搞,还请大佬多多包涵。
文中如有不恰当的地方还请大佬在评论区指出。