算法笔记3

来源:互联网 发布:excel找两列不同的数据 编辑:程序博客网 时间:2024/06/07 03:39


树的遍历

树的遍历分为先序遍历,后序遍历 和 中序遍历。他们分别有自己的用途。

先序遍历:目录结构的显示,文件夹下文件名称

publish void list(File f){   list(f,0);}public void list(File f ,int depth){   printName(f, depth);   if(f.isDirectory()){       File[] files = f.listFiles();       for(File file : files){          list(file, depth+1);       }   }}
后序遍历:统计文件夹的大小

private long totalSize(File f){    long size = 0;    if(f.isFile()){       size = f.length();    }else{       File[] files = f.listFiles();       for(File file : files){         size +=totalSize(file);       }    }  return size;}
中序遍历:做表达式树。得到中缀表达式。


查找

二分查找

  我们使用索引数组来标识,查找的key。首先使用中间键和要查找的比较,如果比中间小则在左边继续找中间键,查找。反之右侧。直到找到。


二叉查找树(二叉搜索树)bst

  将链表插入的灵活性和有序数组的高效性 结合。使用两个结点含有两个链接(链表每个结点只含一个链接)的二叉查找树。

  与最大堆不同,最大堆,是根节点总是比左右子结点,大

  而二叉搜索树,对于任意结点,其左子结点总是小于本身,其右子节点总是大于本身。


  每个结点就是一个对象的key,如果要查找x节点,则与根节点比较,如果x小于根节点,则与左子树的根节点比较。相等则停止,或者返回null

 search(x,k){

     if(x==null || x.key == k){

        return x;

     }

     if(k<x.key){

       return search(x.left , k);

    }else {

       return search(x.right, k);

    }

 }

  

前驱和后继:结点x的前驱是指小于x的结点。x的后继是指大于x的结点。


BST插入,和查找是一样的,知道遇到null则插入。

BST删除 分为三种情况(删除Z)

1.如果Z结点没有孩子结点,只需要删除

2.如果Z结点只有一个孩子,那么将孩子提到Z位置,修改Z的父节点。

3.如果Z结点有2个以上的孩子,那么查找Z的后继Y,后继一定再Z的右子树,然后将Y替换Z



删除4,那么补上来的 肯定满足BST性质,比2大比6小。所以我们把4往下挪,直到变成叶子为止。那么需要往左移一位,然后一直向右挪,遇到大的找左子结点。(右为先,无右或者比右小,则找左)



平衡二叉查找树(AVL)

为何会有平衡二叉树呢,是因为BST只要是一棵树即可,但是也有比较差的情况,比如一直向右插,也满足BST,但它就成为一个链表了。造成这棵树非常不平衡。

但是我们做不到绝对的平衡。只有(2^n-1)个结点才可以做到绝对平衡。所以有了一个“高度”概念。


离根节点最远的叶子,为0,如果最远叶子这一行,有叶子结点,则高度就是深度。如果没有则深度+1

最后如果满足高度都相等,则为平衡二叉树。


平衡二叉树之2-3树

和二叉树不一样,2-3树每个节点保存一个或者两个值。

对于普通的2-节点,必含一个数据项,他保存1个key和左右两个子节点。(一个元素和两条子连接)

  保存一个key及对应value(这是根节点),以及两个指向左右节点的节点。(两个元素和三条子连接其查找关键字大于左孩子的查找关键字,而小于右孩子的查找关键字。

而扩展的3-节点,他有3个子节点,必含两个数据项,其查找关键字S和L满足,S大于左孩子的查找关键字。小于中孩子的查找关键字。L大于中孩子,而小于右孩子。


  在这两种情况互相配合下,可以完成平衡二叉树。如何构造呢(如何一个节点一个节点插入)。

  如果将值插入一个2-节点,则将2-节点扩充为一个3-节点。

  如果将值 插入一个3-节点分为多种情况。

  1.3-节点没有父节点,即整棵树只有它三个节点。此时,将3-节点扩充为4-节点(3-节点是根据元素个数来算的),然后将其变成一颗二叉树。


2.3-节点有一个2-节点的父节点。此时,3-节点扩充为4-节点,然后分解4-节点,然后将分解后的新树的根节点,融入到。2-节点中。


3.3-节点有一个3-节点的父节点,此时,依然将3-节点扩充为4-节点。然后分解4-节点,向上融合。这样上面的3-节点扩充,然后融合,分解,直到父节点为2-节点为止。


我们发现改编成为代码就非常麻烦和复杂,因此红黑树出现了。逻辑依然是这个逻辑,但是由于红黑标记小技巧,最后代码量不大。


平衡二叉树之红黑树

  上面那我们介绍了BST树,那么可能出现最差的链状。最好的情况是平衡二叉树,为了解决这一问题。红黑树应运而生。

  了解红黑树之前,需要理解上面的2-3树。

  红黑树中,所有的节点都是2-节点,为了体现3-节点,这里将3-节点的两个元素用左斜红色连接起来。(红连接只能是左链接)


黑色标记节点就是普通节点。“从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点”

黑色树是平衡的。



JDK1.8中hashMap底层的链表查找key,当链表超过阈值(8),就将链表转换为红白树



原创粉丝点击