树是什么?
树可以理解成是一种分层的数据结构,你也可以看成是‘倒’树,为什么可以这么说呢?看下面的图就能明白了,下面引用一张《C++数据结构和算法》的关于树的图解。
可以看到数据结构中的树,神似一棵倒立成长的大树,根节点只有一个,但是下面的枝叶非常的茂盛。
在现实中,树可以用来表示一些事物的层次结构,比如大学的学院和系的层次,系和专业之间的层次,还有家族谱也可以使用树来表示,下面再次引用一张图,具体自己去体会下,数据结构其实很多都可以映射到现实生活某一类具体的事务。
二叉树是什么?
那么二叉树是什么呢?我们都知道链表是一种线性的数据结构,可以用一条线来链接所有的数据,链式结构方便了数据的插入和移除,但是普通链表(不包括跳跃链表)有一个缺陷,就是在定位某一个元素所花费的时间复杂度较高,因为需要遍历整个链表,双向链表还要好些。首尾都能遍历,单向链表只能从一个方向遍历,简直是悲剧,那么有没有什么方式可以改进这个问题呢?
别着急,我们先来看下二叉树的一个节点中包含的数据。
// 二叉树的某一个节点中包含的数据
TreeNode<T>{
TreeNode left; // 左子节点
TreeNode right; // 右子节点
T t; // 节点上的元素
}
看到上面是不是很熟悉?这不就是双向链表吗?哈哈哈,可以这么理解,当某种极端的情况下,二叉树其实就是一个双向链表。那他们到底有什么区别呢?
好了,我们回到前面的问题,要如何去改进链表定位元素位置的时间复杂度高的问题呢?
二分查找法大家应该都熟悉吧,这是加快数据定位的一种最简单的算法,我们都知道二分查找法之所以快,是因为我们事先对数据进行了排序,排序之后数据有了一个明显递增或者递减结构,通过比较中间数的大小,可以避免遍历整块数据的尴尬
那我们可不可以考虑对链表进行排序呢?看到此处你就应该想到了,二叉树可以简单的理解成对链表进行排序,但就算链表排序后还是线性结构,如果我们只能拿到链表表头的数据的话,那还是很尴尬的
因此我们有必要创造一种新的数据结构,二叉树就应运而生了,这样有助于我们快速定位数据,至于定位的方式有点类似于二分查找法,有空再说说吧。
换而言之,二叉树要满足数据的有序性,那么必然需要一个比较严格的规定
rigth > left
结合前面对二叉树内部节点的数据定义,可以知道,二叉树在插入数据时,右子节点一定要大于左子节点,也就是传说中右插和左插,下面用一张图来说明下,盗图盗图我是搬运工!
// 假设我们有一组这样的数据
int[] arr = {13,25,10,2,12,20,31,29} // 将其变为一个以13为根节点的二叉树,最终会呈现下方这个图
// 再上一组伪代码
if( 待插入数据 > 当前节点){
就插入右边
}else{
插入左边
}
// 当然这只是最简单的说明,二叉树可没有这么简单,有空再上点实际代码吧
总结一下
二叉树 ---- 其实最简单的理解呢,就是一个排序过的双向链表,但是我们每一次只能拿到的树的根节点,并不是链表的表头,你可以理解成插入链表的第一个数据,但是切记他最终呈现的是树状的数据结构哦!链表是线性的!这是有本质区别的,链表的内部节点是分为前置节点和后置节点,二叉树是左子节点和右子节点