搜索概念

       遍历树结构和图结构的方法   必须访问到每个节点而且每个节点只能访问一次

       遍历节点的顺序不同分成了深度优先搜索和广度优先搜索

深度优先搜索和广度优先搜索_广度优先搜索

深度优先搜索

       通过递归或者手动维护一个栈来实现

      递归调用的普通循环遍历的执行流程的区别
         1.普通循环是依次执行必须等当次循环完毕后再执行下一次循环
         2.递归是不需要等当次循环执行完毕而是直接在本次循环中进入下次循环

visited = set()
#首先传入的是root节点1
def dfs(node,visited):

    #判断递归的终止条件
    if node in visited:
        return

    #传入root节点后首先标示root节点1已经被访问
    visited.add(node)

         #1

     #2   5    9

    #3   6  8  10

   #4     7

    for next_node in node.children(): #[2,5,9]
        #root节点1的children集合是[2,5,9]
        if next_node not in visited:
            #2的children是3
            #3的children是4
            #4的children是空,退出根节点是2的搜索
            #开始搜索根节点是5的搜索
            dfs(next_node,visited)
            #整个树的遍历流程就是(深度遍历)
            #1,2,3,4
            #5,6,7
            #8
            #9,10

            #递归调用的普通循环遍历的执行流程的区别在于
            #普通循环是依次执行必须等当次循环完毕后再执行下一次循环
            #递归是不需要等当次循环执行完毕而是直接在本次循环中进入下次循环

深度优先

 

广度优先搜索

      通过循环迭代和队列的方式来对元素进行遍历   广度优先搜索不能使用递归来实现

from collections import deque

def levelOrder(root):

    levels = []
    if not root:
        return levels

    level = 0
    queue = deque([root,])

    while queue:
        levels.append([])
        level_length = len(queue)

        for i in range(level_length):
            node = queue.popleft()
            levels[level].append(node.val)

            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)

        level +=1

    return levels

广度优先

 

优先级优先搜索

         按照元素的优先级来遍历树结构中的所有元素  实现各种推荐给用户消息的功能

分治递归

    分治和普通递归不同的地方在于    分治递归需要把每次调用函数返回的结果进行一个组合操作

    重点:

        1.如何把一个大的问题分解成各个不同的子问题
        2.如何把各个子问题的处理结果汇总到一起

    代码步骤
      1.设置递归终结条件
      2.处理当前调用业务逻辑(把一个大问题切割成不同的小问题)
      3.调用函数自身
      4.合并所有处理子问题的结果
      5.清理当前层的状态

    思路分析:

      求x^n的时候一般的时间复杂度是O(N),在优化的时候可以向O(logN)进行考虑
      2^10   =    2^5 *  2^5
      2^5 =     2^2 *   2^2  *  2
     求x^n结果的时候就转换成求x^(n/2) 时间复杂度就变成了O(logN)
     大问题是求x^n的值
     切割后的子问题就变成了求x^(n/2)的值

深度优先搜索和广度优先搜索_搜索_02

深度优先搜索和广度优先搜索_搜索_03

回溯算法

   

深度优先搜索和广度优先搜索_递归_04

    设置board[i][j]="".等于一个特定变量值如("."),然后再进行递归调用,当某次递归的结果是不期望的就重新设置标识变量board[i][j]="." 如此便回到了起始循环位置