提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 函数声明
- 函数实现
前言
提示:这里可以添加本文要记录的大概内容:
今天将最近所学的关于二叉树的所有知识写出博客,比如:深度遍历,层序,计算结点个数等各种的函数实现(c语言),希望能帮助大家。
函数声明:(依次按顺序写函数实现)
#include <stdio.h> #include <stdlib.h> #include <assert.h> //树的实现 typedef char BTDataType; //结点的结构 typedef struct BinaryTreeNode { BTDataType data; struct BinaryTreeNode* left; struct BinaryTreeNode* right; }BTNode; #include "queue.h" //通过前序遍历将数组"ABD##E#H##CF##G##"构建成二叉树,其中#代表空结点 BTNode* BinaryTreeCreate(BTDataType* a, int* sub); void BinaryTreeDestory(BTNode* root);//销毁二叉树 int BinaryTreeSize(BTNode* root);//计算二叉树节点个数 //查找值为 a 的结点 BTNode* BinaryTreeFind(BTNode* root, BTDataType a); //计算二叉树叶子节点的个数 int BinaryTreeLeafSize(BTNode* root); //计算二叉树第k曾的结点个数 int BinaryTreeLevelKSize(BTNode* root, int k); void BinaryTreePrevOrder(BTNode* root);//前序遍历 void BinaryTreeInOrder(BTNode* root);//中序遍历 void BinaryTreePostOrder(BTNode* root);//后序遍历 void BinaryTreeLevelOrder(BTNode* root);//层序遍历 bool BinaryTreeComplete(BTNode* root);//判断二叉树是否是完全二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* sub);
//通过前序遍历将数组"ABD##E#H##CF##G##"构建成二叉树,其中#代表空结点
//牛客网上有这个题目
//通过前序遍历将数组"ABD##E#H##CF##G##"构建成二叉树,其中#代表空结点 //a 为字符数组,包含上面这串字符, sub记录数组下标,从0开始 BTNode* BinaryTreeCreate(BTDataType* a, int* sub) { //如果为#则直接返回空结点,并且让下标位置加 1 if (a[*sub] == '#') { (*sub)++; return NULL; } //不为空则创造结点,并初始化值,让下标位置加 1 BTNode* root = (BTNode*)malloc(sizeof(BTNode)); root->data = a[(*sub)++]; //同理,构建左儿子和右儿子 root->left = BinaryTreeCreate(a, sub); root->right = BinaryTreeCreate(a, sub); return root; }
void BinaryTreeDestory(BTNode* root)//销毁二叉树
void BinaryTreeDestory(BTNode* root)//销毁二叉树 { //运用递归的思想,在最后碰到空结点是结束当前函数 if (root == NULL) return; //使用后序遍历销毁二叉树,前,中,后在下面有专门的函数 BinaryTreeDestory(root->left); BinaryTreeDestory(root->right); free(root); }
int BinaryTreeSize(BTNode* root)//计算二叉树节点个数
//力扣上有原题
int BinaryTreeSize(BTNode* root)//计算二叉树节点个数 { /*运用分治的思想,将一课树非为根,左子树,右子树 分好的左子树又可以分为根,左子树,右子树,知道碰到空*/ if (root == NULL) return 0; //不为空时则 +1 将当前结点带入计算 return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1; }
//查找值为 a 的结点
BTNode* BinaryTreeFind(BTNode* root, BTDataType a)//查找值为 a 的结点 BTNode* BinaryTreeFind(BTNode* root, BTDataType a) { if (root == NULL) return NULL; //找到就返回找到的结点 if (root->data == a) return root; //对返回的值进行检查,没找到的话就是返回的空,非空就继续返回上一层,直到结束 BTNode* leftret = BinaryTreeFind(root ->left, a); BTNode* rightret = BinaryTreeFind(root ->right, a); if(leftret != NULL) return leftret; if (rightret != NULL) return rightret; return NULL; }
//计算二叉树叶子节点的个数
int BinaryTreeLeafSize(BTNode* root)//计算二叉树叶子节点的个数 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); }
//计算二叉树第k曾的结点个数
int BinaryTreeLevelKSize(BTNode* root, int k)//计算二叉树第k曾的结点个数 int BinaryTreeLevelKSize(BTNode* root, int k) { //在每次递归时,对k进行 -1,这样在k == 1时就到达了第k层 //从而计算k层的节点个数,与普通的计算结点个数类似(深度从1开始) //检查k assert(k > 0); if (root == NULL) { return 0; } if (k == 1) return 1; return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1); }
前,中,后序
//只是改变了访问根节点的顺序,三个函数都类似
void BinaryTreePrevOrder(BTNode* root)//前序遍历 { if (root == NULL) return; printf("%c ", root->data); BinaryTreePrevOrder(root->left); BinaryTreePrevOrder(root->right); return; } void BinaryTreeInOrder(BTNode* root)//中序遍历 { if (root == NULL) return; BinaryTreePrevOrder(root->left); printf("%c ", root->data); BinaryTreePrevOrder(root->right); return; } void BinaryTreePostOrder(BTNode* root)//后序遍历 { if (root == NULL) return; BinaryTreePrevOrder(root->left); BinaryTreePrevOrder(root->right); printf("%c ", root->data); return; }
void BinaryTreeLevelOrder(BTNode* root)//层序遍历
//这里要用到队列,可以自己手写,也可以用c++自带的,这里本人用的是自己写的
//这是队列的函数声明,并将树的节点重命名 typedef struct BinaryTreeNode* QDataType; typedef struct QueueNode { struct QueueNode* next; QDataType data; }QNode; typedef struct Queue { QNode* head; QNode* tail; int size; }Que; void QInit(Que* pa);//初始化队列 void QDestory(Que* pa);//销毁队列 bool QueueEmpty(Que* pa);//判断队列是否为空 void QueuePush(Que* pa, QDataType x);//添加数据 void QueuePop(Que* pa);//删除数据 QDataType QueueFront(Que* pa);//取队头的数据 QDataType QueueBack(Que* pa);//取队尾数据void BinaryTreeLevelOrder(BTNode* root)//层序遍历 { assert(root); //创建队列 Que q1; QInit(&q1); QueuePush(&q1, root); while (!QueueEmpty(&q1)) { QDataType tem = QueueFront(&q1); QueuePop(&q1); printf("%c ", tem->data); if(tem ->left) QueuePush(&q1, tem->left); if(tem->right) QueuePush(&q1, tem->right); } printf("\n"); QDestory(&q1); }
bool BinaryTreeComplete(BTNode* root)
//判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)//判断二叉树是否是完全二叉树 { assert(root); //创建队列 Que q1; QInit(&q1); QueuePush(&q1, root); while (!QueueEmpty(&q1)) { QDataType tem = QueueFront(&q1); QueuePop(&q1); if (tem == NULL) { break; } QueuePush(&q1, tem->left); QueuePush(&q1, tem->right); } while (!QueueEmpty(&q1)) { QDataType tem = QueueFront(&q1); QueuePop(&q1); if (tem != NULL) { QDestory(&q1); return false; } } QDestory(&q1); return true; }
9500

被折叠的 条评论
为什么被折叠?



