目录
引入树
在说树之前,我们先回想一下链表,在当前节点保存下一节点的引用,类时的如下:
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
我们用过链表会发现,我们要想在链表中搜索或者访问一个元素时特别麻烦的,时间时间复杂度是O(N)的,为什么搜索和访问那么慢呢?? 我们仔细一想
- 1.链表一个线性结构,只能从头到尾的遍历元素得到需要的值,并不像数组可以通过下标取得。
- 2.我们存入数据的时候,这个是一个无序的过程,我们只知道有数据进来就马上存进去。
树
假如从这两点入手的话,那么我们应该可以加快链表的搜索和访问的速度。某些研究人员发现,可以在这个链表的基础上,增加多一个节点的引用,即现在一个节点中有多个不一样的节点引用。
- 1.当前节点存入上一节点和下一节点的引用(双向链表)
- 2.当前节点存入多个下一节点的引用(树)
我们把一个节点中存入多个下一节点的数据结构称为树,首节点称为根节点,如图:
树:每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树。
二叉树
上图是树这种数据结构的定义,我们比较长用到的二叉树有是怎么样的呢?如图:
二叉树:是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。
上面这图也称完全二叉树
假设这个树有K层,此树前提是二叉树,K-1层必须是满的,K层左边(左子树)必须先满右边才能为空。
那么这样的数据结构是否可以增加访问速度呢?相比链表,在以知元素是在哪个子树,或许可以加快访问速度。在不知元素位置的时候,也是不能加快访问速度的,这还是一种无序的状态,需要访问元素还是需要遍历一次才可以找到。
⼆叉搜索树
某研究人员又发现,假如固定左边子树小于根节点,右边子树大于根节点,让元素存入的时候就排序好,那么访问速度就加快了,我们称这样的树为二叉搜索树。
它或者是一棵空树,或者是具有下列性质的二叉树:
⼆叉搜索树(英语: Binary Search Tree),也称⼆叉搜索树、有序⼆叉树(英语: ordered binary tree),排序⼆叉树(英语:sorted binary tree),是指⼀棵空树或者具有下列性质的⼆叉树:
1. 若任意节点的左⼦树不空,则左⼦树上所有结点的值均⼩于它的根结点的值;
2. 若任意节点的右⼦树不空,则右⼦树上所有结点的值均⼤于它的根结点的值;
3. 任意节点的左、右⼦树也分别为⼆叉查找树。
红黑树
假如有这样一个业务场景,一批已经排序好的数据,要找一个数据结构加快访问和搜索数据,那么二叉搜索树合适吗??仔细想象。
因为数据是排序好的,假如我们使用这种由序的二叉搜索树之类数据结构,那么最后存完数据后,这颗树就只有左节点或者右节点,实际变成一个链表了。
为了改变二叉搜索树存在的不足,对二叉搜索树进行改进,使整颗树可以自平衡,他将这种排序二叉树称为“对称二叉B树”、“红黑树”。