首页 > 其他分享 >day11

day11

时间:2024-06-11 20:13:27浏览次数:11  
标签:node TreeNode st day11 root stack append

今日day11:三种二叉树的遍历方式
1 首先是递归遍历。需要首先搞懂前序中序后序遍历的意思,即以根root的位置为准
前序即根左右 中序即左根右 后序即左右根
递归则是指在函数中循环调用自身直至跳出递归条件
python实现
原理仅有遍历顺序的变化为区别,首先声明一个空res数组用以存放数值,遍历即依次获取树各节点的值,递归的条件是root仍然存在,由于二叉树的各子树仍然满足二叉树之定义因此当访问到根时就将值送入res数组,再调整root去找左右节点,而左右节点为根时仍然满足二叉树定义即实现了遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
"前序"
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def dfs(root):
            if root:
                res.append(root.val)
                dfs(root.left)
                dfs(root.right)
        dfs(root)
        return res
"中序"
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def dfs(root):
            if root:
                dfs(root.left)
                res.append(root.val)
                dfs(root.right)
        dfs(root)
        return res
"后序"
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def dfs(root):
            if root:
                dfs(root.left)
                dfs(root.right)
                res.append(root.val)
        dfs(root)
        return res

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

 //前序
 func preorderTraversal(root *TreeNode) []int {
    var dfs func(node *TreeNode)
    var res []int
    dfs = func(node *TreeNode){
        if node == nil {
            return
        }
        res = append(res,node.Val)
        dfs(node.Left)
        dfs(node.Right)
    }
    dfs(root)
    return res
}

//中序
func inorderTraversal(root *TreeNode) []int {
    var dfs func(node *TreeNode)
    var res []int
    dfs = func(node *TreeNode){
        if node == nil{
            return
        }
        dfs(node.Left)
        res = append(res,node.Val)
        dfs(node.Right)
 }
 dfs(root)
 return res
}

//后序
func postorderTraversal(root *TreeNode) []int {
    var dfs func(node *TreeNode)
    var res []int
    dfs = func(node *TreeNode){
        if node == nil {
            return 
        }
        dfs(node.Left)
        dfs(node.Right)
        res = append(res,node.Val)
    }
    dfs(root)
    return res
}

2 其次是迭代遍历,该法旨在使用栈作为暂存值的结构并根据遍历顺序适当调整

"先使用数组存储root,一旦其存在就将值弹出即先进后出,再将其追加至result中,然后由于栈是先进先出,所以先右后左"
"先序"
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        stack = [root]
        result =[]

        while stack:
            node = stack.pop()
            result.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return result

"中序"
"先不要将root放入stack中,使用指针指向root以供操作,该方法旨在先将根加入栈中再访问其左节点然后先出左节点后此时又指向右节点,再令其找右节点如上操作,则完成了中序"
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        stack = []
        result = []
        cur = root
        while cur or stack:
            if cur:
                stack.append(cur)
                cur = cur.left
            else:
                cur = stack.pop()
                result.append(cur.val)
                cur = cur.right
        return result
"后序"
"基本操作如前序,但考虑到栈的先进先出,我们将其位置调整为根右左并反转,这样就成为了左右根"
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            result.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return result[::-1]
//先序
//借助双端链表list及其中的函数
func preorderTraversal(root *TreeNode) []int {
    ans := []int{}
    if root == nil {
        return ans
    }
    st:=list.New()
    //尾插root
    st.PushBack(root)

    for st.Len() > 0{
        //弹出末尾节点并声明其类型为treenode
        node := st.Remove(st.Back()).(*TreeNode)
        ans = append(ans,node.Val)
        if node.Right != nil{
            st.PushBack(node.Right)
        }
        if node.Left != nil {
            st.PushBack(node.Left)
        }
    }
    return ans
}

//中序
func inorderTraversal(root *TreeNode) []int {
    ans :=[]int{}
    if root == nil{
        return ans
    }
    st := list.New()
    cur := root
    for cur != nil || st.Len() > 0 {
        if cur!=nil{
            st.PushBack(cur)
            cur = cur.Left
        }else{
            cur = st.Remove(st.Back()).(*TreeNode)
            ans = append(ans,cur.Val)
            cur = cur.Right
        }
    }
    return ans
}

//后序
func postorderTraversal(root *TreeNode) []int {
    ans := []int{}
    if root == nil {
        return ans
    }
    st := list.New()
    st.PushBack(root)
    for st.Len() >0 {
        node := st.Remove(st.Back()).(*TreeNode)
        ans = append(ans,node.Val)
        if node.Left != nil{
            st.PushBack(node.Left)
        } 
        if node.Right != nil{
            st.PushBack(node.Right)
        }
    }
    reverse(ans)
    return ans
}

func reverse(a []int) {
    l,r := 0,len(a)-1
    for l < r {
        a[l],a[r] = a[r],a[l]
        l,r = l+1,r-1
    }
}

3 最后是统一迭代法:

"前序"
"类似使用栈进行遍历并考虑出栈顺序,但它把元素入结果集的操作统一进行,先完成元素的顺序寻找"
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                if node.right:
                    st.append(node.right)
                if node.left:
                    st.append(node.left)
                st.append(node)
                st.append(None)
            else:
                node = st.pop()
                result.append(node.val)
        return result

"中序"
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                if node.right:
                    st.append(node.right)
                st.append(node)
                st.append(None)

                if node.left:
                    st.append(node.left)
            else:
                node = st.pop()
                result.append(node.val)
        return result
"后序"
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                st.append(node)
                st.append(None)
                if node.right:
                    st.append(node.right)
                if node.left:
                    st.append(node.left)
            else:
                node = st.pop()
                result.append(node.val)
        return result
//前序
func preorderTraversal(root *TreeNode) []int {
    if root == nil {
        return nil
    }
    var stack = list.New()
    res:=[]int{}
    stack.PushBack(root)
    var node *TreeNode
    for stack.Len() > 0{
        e := stack.Back()
        stack.Remove(e)//弹出元素
        if e.Value == nil { //如果为空,则表明需要处理中间节点
            e = stack.Back()//弹出元素
            stack.Remove(e)//删除中间节点
            node = e.Value.(*TreeNode) 
            res = append(res,node.Val)//将中间节点加入到结果集合中
            continue //继续弹出下一个
        }
        node = e.Value.(*TreeNode)
        if node.Right != nil {
            stack.PushBack(node.Right)
        }
        if node.Left !=nil {
            stack.PushBack(node.Left)
        }
        stack.PushBack(node)
        stack.PushBack(nil)
    }
    return res
}
//中序
func inorderTraversal(root *TreeNode) []int {
    if root == nil {
        return nil
    }
    stack := list.New()
    res :=[]int{}
    stack.PushBack(root)
    var node *TreeNode
    for stack.Len() >0 {
        e := stack.Back()
        stack.Remove(e)
        if e.Value == nil {
            e = stack.Back()
            stack.Remove(e)
            node = e.Value.(*TreeNode)
            res = append(res,node.Val)
            continue
        }
        node = e.Value.(*TreeNode)
        if node.Right!=nil {
            stack.PushBack(node.Right)
        }
        stack.PushBack(node)
        stack.PushBack(nil)
        if node.Left != nil{
            stack.PushBack(node.Left)
        }
    }
    return res
}
//后序
func postorderTraversal(root *TreeNode) []int {
    if root == nil {
        return nil
    }
    var stack = list.New()
    res :=[]int{}
    stack.PushBack(root)
    var node *TreeNode
    for stack.Len() >0 {
        e := stack.Back()
        stack.Remove(e)
        if e.Value == nil {
            e = stack.Back()
            stack.Remove(e)
            node = e.Value.(*TreeNode)
            res=append(res,node.Val)
            continue
        }
        node = e.Value.(*TreeNode)
        stack.PushBack(node)
        stack.PushBack(nil)
        if node.Right!=nil{
            stack.PushBack(node.Right)
        }
        if node.Left!= nil {
            stack.PushBack(node.Left)
        }
    }
    return res
}

标签:node,TreeNode,st,day11,root,stack,append
From: https://www.cnblogs.com/leisure535/p/18242633

相关文章

  • day11 Xpath
    网页分析有优势,全称XMLPathLanguage一种小型的查询语言优点:可在XML中查询信息支持HTML的查询通过元素和属性进行导航PY使用需要安装库:安装lxmlselector=etree.HTML(html_doc)//实例化对象,实际上就是一个Element类,通过逻辑运算://div[@idand@class]查找同时拥有的元素......
  • m1_day11
    课程内容:StringBuffer类常见的方法面向对象的高阶特征访问权限修饰符static修饰符final修饰符abstract修饰符单例模式StringBuffer类常见的方法:*append(String):往字符串里面追加连接reverse():翻转字符串insert(int,char):往指定下标处插入......
  • day11_我的Java学习笔记 (static_静态成员变量+静态成员方法_工具类、代码块_静态代码
    0.面向对象进阶1.static静态关键字1.1static是什么,static修饰成员变量的用法Java成员变量成员方法Python类(对象)属性类(对象)方法static修饰成员变量的应用:在线人数统计1.2static修饰成员变量的内存原理1.3static修饰成员方法的基本......
  • [算法刷题打卡]Day11
    1、Leetcode-面试经典150题目20- 14.最长公共前缀思路:1、首先对于空的情况判断,直接返回“”2、对于多个即两个以上的字符串找公共前缀,其实就是先两个两个找公共前缀。道理很简单,ans(S1,S2,S3,S4)= ans(S4,ans(S3,ans(S1,S2)))classSolution{public:string......
  • day11 基础函数(二)
    知识回顾```python#函数:封装具有某种功能的代码块函数的定义def函数名():  代码函数名()#函数调用实参:相当于变量值(演员)形参:相当于变量名(角色) 必须参数(位置参数)就是必须按照正确的顺序将实参传入到函数中,实参和形参个数必须一一对应 默认......
  • day11-模块
    1.自定义模块1.1模块和包importhashlibdefencrypt(data):"""数据加密"""hash_object=hashlib.md5()hash_object.update(data.encode('utf-8'))returnhash_object.hexdigest()user=input("请输入用户名:&quo......
  • javaweb学习(day11-监听器Listener&&过滤器Filter)
    一、监听器Listener1 Listener介绍Listener监听器它是JavaWeb的三大组件之一。JavaWeb的三大组件分别是:Servlet程序、Listener监听器、Filter过滤器Listener是JavaEE的规范,就是接口监听器的作用是,监听某种变化(一般就是对象创建/销毁,属性变化),触发对应方......
  • Leetcode算法训练日记 | day11
    一、有效的括号1.题目Leetcode:第20题给定一个只包括'(',')','{','}','[',']'的字符串s,判断字符串是否有效。有效字符串需满足:1.左括号必须用相同类型的右括号闭合。2.左括号必须以正确的顺序闭合。3.每个右括号都有一个对应的相同类型的左括号。示例1:输入:s="()"......
  • LeetCode刷题Day11(补卡)
    20.有效的括号题目链接:leetcode20.有效的括号文章讲解:代码随想录视频讲解:哔哩哔哩视频这题考察的是栈的使用,遍历字符串,如果是左括号存入栈中,如果是右括号则对比栈的头部是否为与之匹配的左括号,如果不是则返回false,最后若栈为空则正好匹配返回true,详细代码如下:cl......
  • 毕设Day11
     JWT实现用户登录鉴权     ......