• 前序遍历:先访问该节点,然后在递归遍历其左子树,然后再访问其右子树

  • 中序遍历:先递归遍历其左子树,然后访问该节点,然后再递归遍历其右子树

  • 后序遍历:先递归遍历其左子树,然后递归遍历其右子树,然后在访问该节点。

层级遍历,就从上到下,一层一层(这个没什么说的)

有个题目:
某二叉树 中序遍历为:A、B、C、D、E、F、G,后序遍历为:B、D、C、A、F、G、E, 求前序遍历 或者 层级遍历。

解题思路: 必须先通过 前序 或 后序 得到 每个根节点(很关键)  
1.这里通过【后序遍历B、D、C、A、F、G、E】知道,【根节点是E】  
2.那么通过中序遍历得到【ABCD是E的左子树】,【FG是E的右子树】

右子树分析
1.【E的右子树FG】中,通过 中序遍历,EFG 左中右, E是中,【E是根节点】,知道【F】只能是【E的右子树】,【E的左子树】为空,那么【G】如何分析呢?
2.继续【中序 FG】 左中右,已经知道F是中(E没有左子树,F为E的右子树,下面肯定是F的子节点),通过 中序FG 中右,那么【G为F的右子树】

左子树分析
1. 然后就是 分析【E 的左子树】了,【ABCD 是E的左子树】,根据【后序遍历B、D、C、A】 得知【A是E的左子树】(很关键)
2. 然后【ABCD 中A是BCD的根节点】,   根据【中序遍历A、B、C、D】得到【BCD是A的 右子树】
3. 根据【后序B、D、C】 得到【C是A的右子树】
4. 以C作为根节点, 根据中序遍历分析,`A已经是C的根节点`,  直接分析【中序BCD】,C是根节点, 那么【B是C的左子树】,【D是C的右子树】

binary search trees 二叉搜索树

二叉搜索树:有序

二叉搜索树的 查询、插入和删除

随机构建二叉搜索树


AVL树在 算法导论中删除了,(不重要? 暂时先放下这个)

AVL树:是带平衡条件的二叉查找树, 树的深度是O(log N).
平衡条件:
1.最简单的是要求左右子树 具有相同的高度
2.另一种 是 要求每个节点都必须要有相同高度的 左子树和右子树。 (要求太严,放宽了)

AVL树是其每个节点的左子树 和右子树的高度 最多 差1的 二叉查找树。

单旋转,双旋转


红黑树 (重要 红黑树 应用非常广泛)

红黑树是平衡二叉树的一种,它有很好的性质,树中的结点都是有序的,而且因为它本身就是平衡的,

所以查找也不会出现非常恶劣的情况,基于二叉树的操作的时间复杂度是O(log(N))。

RB tree

RB+ tree
RB- tree

Linux内核中的红黑树




Linux内核在管理vm_area_struct时就是采用了红黑树来维护内存块的。

先到include/linux/rbtree.h中看一下红黑树的一些定义,如下:


struct rb_node

{

unsigned long rb_parent_color;

#define RB_RED 0

#define RB_BLACK 1

struct rb_node *rb_right;

struct rb_node *rb_left;

} __attribute__((aligned(sizeof(long))));


struct rb_root只是struct rb_node*的一个包装,这样做的好处是看起来不用传递二级指针了。不错,很简单。再看一下下面几个重要的宏,细心的你一定会发现,rb_parent_color其实没那么简单,Andrea Arcangeli在这里使用了一个小的技巧,不过非常棒。正如名字所暗示,这个成员其实包含指向parent的指针和此结点的颜色!它是怎么做到的呢?很简单,对齐起了作用。既然是sizeof(long)大小的对齐,那么在IA-32上,任何rb_node结构体的地址的低两位肯定都是零,与其空着不用,还不如用它们表示颜色,反正颜色就两种,其实一位就已经够了。


这样,提取parent指针只要把rb_parent_color成员的低两位清零即可:


#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))


取颜色只要看最后一位即可:


#define rb_color(r) ((r)->rb_parent_color & 1)


测试颜色和设置颜色也是水到渠成的事了。需要特别指出的是下面的一个内联函数:


static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, struct rb_node ** rb_link);


它把parent设为node的父结点,并且让rb_link指向node。


我们把重点集中在lib/rbtree.c上,看看一些和红黑树相关的重要算法。开始之前我们一起回忆一下红黑树的规则:


1. 每个结点要么是红色要么是黑色;

2. 根结点必须是黑色;

3. 红结点如果有孩子,其孩子必须都是黑色;

4. 从根结点到叶子的每条路径必须包含相同数目的黑结点。


这四条规则可以限制一棵排序树是平衡的。









红黑树必须满足的规则:

    所有节点都有颜色,要么红色,要么黑色
    根节点是黑色,所有叶子节点也是黑色
    叶子节点中不包含数据
    非叶子节点都有2个子节点
    如果一个节点是红色,那么它的父节点和子节点都是黑色的
    从任何一个节点开始,到其下叶子节点的路径中都包含相同数目的黑节点

红黑树中最长的路径就是红黑交替的路径,最短的路径是全黑节点的路径,再加上根节点和叶子节点都是黑色,

从而可以保证红黑树中最长路径的长度不会超过最短路径的2倍。

 

旋转


B树 B+树



Trie树

又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

In computer science, a trie, also called digital tree and sometimes radix tree or prefix tree (as they can be searched by prefixes), is an ordered tree data structure that is used to store a dynamic set or associative array where the keys are usually strings. Unlike a binary search tree, no node in the tree stores the key associated with that node; instead, its position in the tree defines the key with which it is associated. All the descendants of a node have a common prefix of the string associated with that node, and the root is associated with the empty string. Values are not necessarily associated with every node. Rather, values tend only to be associated with leaves, and with some inner nodes that correspond to keys of interest. For the space-optimized presentation of prefix tree, see compact prefix tree.

http://blog.csdn.net/baisung/article/details/7650360

posted @ 2015-11-04 18:04  scott_h  阅读(158)  评论(0编辑  收藏  举报