前言
这周因为不能出去就尽量把数据结构更完,每天一篇文章发布,请大家监督我,如果我没法请@我催更0.0
三连即可提高学习效率0.0
🧑🏻作者简介:一个学嵌入式的年轻人
✨联系方式:2201891280(QQ)
📔源码地址:https://gitee.com/xingleigao/study_qianrushi
⏳全文大约阅读时间: 120min
文章目录
前言
树的概念
二叉树
二叉树的性质
顺序存储结构
链式存储
二叉树的运算
二叉树的遍历
创建树
先序遍历实现
层序遍历请
写在最后
树的概念
数(Tree)是n(n>=0)个节点的有限集合T,它满足两个条件:
有且仅有一个特定的称为根(Root)的结点
其它结点可以分为m个互不相交的有限集合T1
相关概念:
一个节点的子树个数成为该节点的度数
一棵树的度数是树中节点的最大度数
度数为0的节点称为树叶或终端节点
度数不为0的节点称为分支节点
除根节点外的分支节点称为内部节点
一个节点系列k1,…kj.满足ki是ki+1的父节点称为一条k1到kj的路径
路径长度为j-1,即路径中的边数
路径中前面节点是后面节点的祖先,后面节点是前面节点的子孙
节点的层数等于父节点的层数+1,根节点的层数定义为1,树中结点层数最大值称为该树的高度或深度
树的逻辑结构:
树中任何节点都可以有0个或者等多个直接后继节点(子节点)。但至多只有一个直接前趋节点(父节点),根节点没有前趋节点,叶子节点没有后继节点。
二叉树
二叉树是n(n>=0)个节点的有限集合
空树
一个节点以及两颗互不相交的,分别称为左子树和右子树的二叉树组成。
严格区分左孩子和右孩子,即使只有一个子节点也要区分左右。
二叉树的性质
二叉树第i(i≥1)层上的节点最多为2i-1个。
深度为k(k≥1)的二叉树最多有2k-1个节点。
满二叉树:深度为k(k≥1)有2k-1个节点的二叉树。
完全二叉树:只有最下面两层有度数小于2的节点,且最下面一层的叶节点集中在最左边的若干位置上。具有n个节点的完全二叉树的深度为(log2n)+1。
顺序存储结构
完全二叉树节点的编号方法是从上到下,从左到右,根节点为1号节点。设完全二叉树的节点数为n,某节点编号为i:
i>1(不是根节点)时,有父节点,其编号为i/2;
2i≤n时,有左孩子,其编号为2i ,否则没有左孩子,本身是叶节点;
2i+1≤n时,有右孩子,其编号为2i+1 ,否则没有右孩子;
i为奇数且不为1时,有左兄弟,其编号为i-1,否则没有左兄弟;
i为偶数且小于n时,有右兄弟,其编号为i+1,否则没有右兄弟;
有n个节点的完全二叉树可以用有n+1个元素的数组进行顺序存储,节点号和数组下标一一对应,下标为零的元素不用。
利用以上特性,可以从下标获得节点的逻辑关系。不完全二叉树通过添加虚节点构成完全二叉树,然后用数组存储,这要浪费一些存储空间。
链式存储
数据结构方式:
typedef int data_t ; typedef struct node_t; { data_t data ; struct node_t *lchild ,*rchild ; } bitree_t ; bitree_t *root ;
二叉树的运算
二叉树的遍历
遍历:沿某条搜索路径周游二叉树,对树中的每一个节点访问一次且仅访问一次。
二叉树是非线性结构,每个结点有两个后继,则存在如何遍历即按什么样的搜索路径进行遍历的问题。
由于二叉树的递归性质,遍历算法也是递归的。三种基本的遍历算法如下 :
先访问树根,再访问左子树,最后访问右子树;
先访问左子树,再访问树根,最后访问右子树;
先访问左子树,再访问右子树,最后访问树根;
创建树
bitree * tree_create(){ data_t ch; bitree *r; scanf("%c", &ch); if(ch == '#') return NULL; if((r = (bitree *)malloc(sizeof(bitree)))== NULL){ printf("malloc failed\n"); return NULL; } r->data = ch; r->left = tree_create(); r->right = tree_create(); return r; }
输入AB#CD###E#FGH##K###就能创建成功,就是上面的先序遍历
先序遍历实现
void preorder(bitree *r){ if(r == NULL) return; printf("%c", r->data); preorder(r->left); preorder(r->right); }
先序遍历就是:ABCDEFGHK
剩余的执行过程建议看看gitee代码。
层序遍历请
void layerorder(bitree *r){ linkqueue *lq; if((lq = queue_create()) == NULL) return; if(r == NULL) return; enqueue(lq, r); while(!queue_empty(lq)){ r = dequeue(lq); printf("%c",r->data); if(r->left) enqueue(lq, r->left); if(r->right) enqueue(lq, r->right); } }
输出顺序:ABECFDGHK
写在最后
二叉树的内容我写的比较草,因为我学过了,照着敲一敲就行了,大家也一定要敲一敲然后才能更好的理解,大家加油,接明天就是最后一个数据结构了,就是查找和排序,我尽量一天一更,大家和我一起变强呀!最后三连即可提高学习效率!!!
另外我在更新的就是算法笔记的一些例题笔记,这个系列是用于提高我的算法能力,如果有兴趣对算法领域感兴趣找不到合适的入门文章也可以追更,如果我更新的太慢了请大家点赞收藏,一键三连才能更有更新的动力呀0.0