前面我们介绍了树的基本概念,并引出了二叉树。值得注意的是,无特征的二叉树在工程上几乎没啥用处,一般都是使用bst、avl,trie,rbtree等具有特殊特征的二叉树。
下面,我们先来看一看二叉搜索树。
BST(Binary Search Tree,二叉搜索树)可以提高查找的性能,二叉搜索树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,平均为O(log n),最差为O(n),此时相当于二叉搜索树变成了链表。从这一个特点我们应该不难发现,树,是链表和数组之间的一种平衡,为了获得更好性能的查找、插入和删除方法。
BST的特点是:
1.若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2.若任意节点的右子树不空,则右子树上所有节点的值均大于或等于它的根节点的值;
3.任意节点的左、右子树也分别为二叉查找树;
中序遍历二叉查找树可得到一个关键字的有序序列,一个无序序列可以通过建构一棵二叉查找树变成一个有序序列,建构树的过程即为对无序序列进行查找的过程。每次插入的新的结点都是二叉查找树上新的叶子结点(作为叶子节点插入),在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。
如图1-1所示,即为一颗二叉搜索树:
基本数据定义:
struct crystal_bst_tree {
struct bst_node my_node; int num;};int bst_insert(struct bst_root *root, struct crystal_bst_tree *tree)int bst_insert(struct bst_root *root, struct bst_node *tree)
bst_insert函数有两个参数,第一个是根节点,第二个是需要插入的节点,插入节点的定义,可以使用struct crystal_bst_tree *也可以使用struct bst_node *。这两种类型的差别无非是是否需要使用container_of宏处理而已。按照Linux内核设计者们的惯例,我们使用后者,来实现插入操作:
static inline void bst_link_node(struct bst_node * node, struct bst_node * parent, struct bst_node ** bst_link){
node->bst_left = node->bst_ri