算法第七周_字典树和并查集,高级搜索,红黑树和AVL树_20210117

一,字典树

在这里插入图片描述

字典树的基本性质

在这里插入图片描述
在这里插入图片描述
上图展示了字典树中的节点可以存储这个词出现的频次,这样在搜索时就可以根据频次来推荐,当然不限于只存储频次,也可以存储其他信息。
节点的内部实现
在这里插入图片描述
不是使用left和right来实现,而是直接使用字符指向下一个字符,如果只是简单的字母还不区分大小写就是26个分叉,如果是整个字符串的话ASCII码就是255,一共有255个分叉,一般是26个分查的多叉树,如果是叶子节点的话就指向空。
我们在构造字典树的时候可以是动态的,出现一个单词就构造一个分支,最大就是26个分支,所以是非常耗费空间的,一层就是26个分支,
单词的长度就是树的深度,所以查询是非常快的,查询次数等于单词长度,一般就是十几次,这样查询时间比排序+二分查找快很多,所以就得出了字典树的核心思想
在这里插入图片描述
第二条的核心思想有个用处,就是我们只输入了前缀的前几个字母的话,可以把所有的以这个为前缀的候选词都方便的找出来。

二,并查集

并查集不像动态规划那些有很多的可以发挥的空间,并查集是有固定的使用场景和代码模板,在使用的时候直接调用现成的代码就好,这类题目比较固定,
适用场景:
在这里插入图片描述

并查集的基本操作:
在这里插入图片描述
1.创建一个并查集,使用数组或者set
并查集初始化:
在这里插入图片描述

并查集每个元素都有一个parent数组指向自己,说明自己是自己的集合。

合并查询:
在这里插入图片描述
查询:
从一个元素去找他的parent,,然后再找parent的parent,一直往上,直到元素的parent等于他自己的时候说明找到了领头羊。
合并:
将一个集合的领头元素指向另一个集合的领头元素。

路径压缩:
在这里插入图片描述
将一条路径上的元素的parent都指向a,这样和原来的表还是一样的,好处是查询的时间会快很多

并查集的Python实现:
在这里插入图片描述
首先创建并查集并遍历二维数组,当M[i][j]=1时合并ij,
最后看这个并查集李到底有多少个孤立的集合

路径压缩的作用是将所有的元素的parent指向根节点,这样的好处是下次再查找元素的parent时,时间时O(1)的。

怎么判断是否可以使用并查集:
类似于朋友圈,任意给两个人判断他们是不是朋友之类的问题。
一个比较好的并查集介绍

上面连接提供的代码模板:

class UnionFind:
    def __init__(self):
        """
        记录每个节点的父节点
        """
        self.father = {
    
    }
    
    def find(self,x):
        """
        查找根节点
        路径压缩
        """
        root = x

        while self.father[root] != None:
            root = self.father[root]

        # 路径压缩
        while x != root:
            original_father = self.father[x]
            self.father[x] = root
            x = original_father
         
        return root
    
    def merge(self,x,y,val):
        """
        合并两个节点
        """
        root_x,root_y = self.find(x),self.find(y)
        
        if root_x != root_y:
            self.father[root_x] = root_y

    def is_connected(self,x,y):
        """
        判断两节点是否相连
        """
        return self.find(x) == self.find(y)
    
    def add(self,x):
        """
        添加新节点
        """
        if x not in self.father:
            self.father[x] = None

作者:MiloMusiala
链接:https://leetcode-cn.com/problems/number-of-provinces/solution/python-duo-tu-xiang-jie-bing-cha-ji-by-m-vjdr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三,高级搜索

高级搜索的基础是对DFS,BFS这种初级搜索要熟悉
复习初级搜索:在这里插入图片描述

初级搜索的内涵就是暴力搜索,初级搜索的优化方向是剪枝和和搜索方向。
像DFS这种就是傻瓜式搜索,不撞南墙不回头,没有任何的智能性,接下来这一部分会讲到优化的高级搜索:双向搜索和启发式搜索。

双向搜索:从起点和终点分别做一个广度优先,然后在中间相遇,这样时间更快。

启发式搜索:使用优先队列的数据结构,是按照节点的优先级,优先级高的先拿出来搜索,启发式搜索又叫A算法或者优先级搜索。

从零钱置换理解搜索问题:
在这里插入图片描述
搜索问题就是在状态树里使用DFS,或者BFS,优先级优先等方法得到最终我们想要的最优解,或者统计分支的个数。

3.1 剪枝

在状态树进行搜索的时候,如果我们发现某个分支是处理过的,我们就可以将其放在缓存中,整个分支就可以剪掉,不需要手动进行计算,有时候的话这个分支不够好,就是较差或者次优的分支,我们也可以将其剪掉.

3.2 双向BFS

从两端向中间扩散,当两端相遇时,结束,两边的步数相加就是最后的步数。

3.3 启发式搜索

是一种一遍搜索,一遍有思考的搜索方式,可以理解为思考式搜索,本质是通过优先级不断地去找优先级高的。

启发式搜索是基于BFS的:
在这里插入图片描述
代码模板如下:
在这里插入图片描述
在这里插入图片描述
启发式搜索的核心就是找到估价函数。
A*算法和BFS的对比

红黑树,AVL

复习:

二叉树
树的前中后序遍历
二叉搜索树
在这里插入图片描述
在极端情况下会出现棍子的情况,如下:

这个时候我们就需要用到了平衡二叉树,常用的平衡二叉树是AVL和红黑树。以及treap,splay(伸展树),B+树,二三树(应用在数据库的索引结构)
平衡二叉树的wiki

如何平衡二叉树:

AVL树

在这里插入图片描述
平衡二叉树

在这里插入图片描述

旋转操作:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
动画

总结:
在这里插入图片描述
在这里插入图片描述

红黑树

是一种近似的平衡二叉树
在这里插入图片描述
在这里插入图片描述

重点:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/a18829292719/article/details/112588375