Python数据结构与算法-树

一、树的概念

详情见 https://blog.csdn.net/little_limin/article/details/129845592

Python数据结构与算法-堆排序(NB组)—— 一、树的基础知识

二、树的实例:模拟文件系统

1、树的存储

树结构也是链式存储的,与链表的结构相似,只是树存在多个子节点,不是线性的,存在一堆多的情况。与双链表相似,只不过链表节点对应的下一个节点只有一个,树节点对应的孩子节点很多,需要用列表[]存储。

(1)树节点代码实现

# 树节点的类
class Node(): # 创建文件节点的类,及其属性(父节点,孩子节点)
    def __init__(self, name, type = "dir"):  # 节点初始属性,文件名,文件类型
        self.name = name  # 文件名
        self.type = type # 文件类型
        # 文件相互间关系
        self.children = [] # 孩子节点,孩子节点可以有很多,所以是列表
        self.parent = None # 父节点,父节点只有一个的,不一定需要有这个指向

# print测试
n = Node("hello") #父节点
n2 = Node("world") #孩子节点1
n3 = Node("yoyo") # 孩子节点2
# 孩子节点与父节点关联
n.children.append(n2) 
n.children.append(n3)
n2.parent = n
n3.parent = n
# 打印孩子节点的属性
for nm in n.children:
    print(nm.name)

(2)输出结果

world
yoyo

2、模拟文件系统

(1)代码实现

# 树的实例:模拟文件系统
# 树是链式存储
class Node(): # 创建文件节点的类,及其属性(父节点,孩子节点)
    def __init__(self, name, type = "dir"):  # 节点初始属性,文件名,文件类型
        self.name = name  # 文件名
        self.type = type # 文件类型
        # 文件相互间关系
        self.children = [] # 孩子节点,孩子节点可以有很多,所以是列表
        self.parent = None # 父节点,父节点只有一个的,不一定需要有这个指向

    def __repr__(self): # 内置函数,返回值
        return self.name  # 返回名字

class FileSystemTree(): # 创建文件根目录——数据结构(树)
    def __init__(self) -> None: # 树的属性
        self.root = Node("/")  # 树的根节点,类似于链表的head结点 
        self.now = self.root # now指针,当前目录

    def mkdir(self,name):  # 当前目录创建文件
        # 保证name以/结尾
        if name[-1] != "/": # name这个字符串的最后一位不是斜杠
            name += "/"  # 在name的最后加上斜杠
        new_dir = Node(name)  # 创建文件节点
        # 创建与当前文件夹的连接
        self.now.children.append(new_dir)  
        new_dir.parent = self.now 

    def ls(self):  # 展现当前目录下的所有子目录
        return self.now.children  # 返回子目录列表
    
    def cd(self,name): # 切换目录(到子目录),支持向上返回
        # 判断是否为文件夹
        if name[-1] != "/":
            name += "/"

        if name == "../": #当前目录
            self.now = self.now.parent  # 返回目录到上级
            return
        # 找到和name相同的文件
        for child in self.now.children:
            if child.name == name: 
                self.now = child # 切换目录到child
                return  # 输出
        # 子目录中无该文件夹,报错
        raise ValueError("invaild dir")
    
tree = FileSystemTree() # 创建树

# 新建文件夹
tree.mkdir("Var/")
tree.mkdir("bin/")
tree.mkdir("usr/")
print(tree.ls()) # 展示当前子目录

# 切换到子目录
tree.cd("bin/")
tree.mkdir("python/") # 子目录中创建文件夹
print(tree.ls()) # 展示当前子目录

# 切换回上级目录
tree.cd("../")
print(tree.ls()) # 展示当前子目录

(2)代码结果

[Var/, bin/, usr/]
[python/]
[Var/, bin/, usr/]

3、模拟文件代码相关知识点

(1)__repr__ 和__str__ 内置函数的用法和示例

1)__repr__的作用

输出实例对象时,其内容由__repr__的返回值决定。

class Test:
    def __repr__(self) -> str:
        return "hello"

t = Test()
print(t)

输出结果

hello

可以看到,当打印实例对象的时候,打印的结果就是__repr__的返回值。如果不加定义__repr__则会默认使用object__repr__函数,返回如下:

<__main__.Test object at 0x0000023573CF0700>

2)__str__作用

与__repe__作用相同,只不过__str__要更猛一点,当你的类中同时重写了__str____repr__后,那么当你打印实例对象的时候,python底层会优先执行实例对象.__str__()。

class Test:
    def __repr__(self) -> str:
        return "repr"
    
    def __str__(self) -> str:
        return "str"

t = Test()
print(t)

输出结果

str

通过上面这个例子可以看到,输出的是__str__的返回值(__repr__没抢过__str__)。

(2)__str__和__repr__区别

在代码编辑器中执行print()函数,python优先调用print(实例对象.__str__());而当在运行终端直接敲实例对象的时候,python底层执行的其实是实例对象.__repr__()。

示例1:在终端直接打印

>>> from text import Test
>>> t = Test()
>>> t
repr
>>> print(t)
str

示例2:在编辑器print()

class Test:
    def __repr__(self) -> str:
        return "repr"
    
    def __str__(self) -> str:
        return "str"

t = Test()
print(t)

输出结果:

str

(3)文件的相对路径和绝对路径

相对路径从当前目录到文件所在位置;

绝对路径从根目录开始到文件所在地。

(4)python的"./"、"../"和"/"路径

  • ./代表目前文件所在的目录。

  • . ./代表目前文件的上一层目录。

  • /代表根目录。

三、二叉树

1、概念

详情见 https://blog.csdn.net/little_limin/article/details/129845592

Python数据结构与算法-堆排序(NB组)—— 二、二叉树的基础知识

2、二叉树的存储

(1)二叉树的链式存储

将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接。

(2)节点存储代码

class BiTreeNode: # 二叉树
    def __init__(self,data): # data:节点数据
        self.data = data
        self.lchild = None # 左孩子
        self.rchild = None # 右孩子

3、二叉树代码实现

# 二叉树的简单实现

class BiTreeNode(): # 二叉树节点
    def __init__(self,data) -> None: 
        self.data = data
        self.lchild = None
        self.rchild = None

# 定位节点
a = BiTreeNode("A")
b = BiTreeNode("B")
c = BiTreeNode("C")
d = BiTreeNode("D")
e = BiTreeNode("E")
f = BiTreeNode("F")
g = BiTreeNode("G")

# 节点关系链接
e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f

# 根节点
root = e

print(root.lchild.rchild.data)

结果输出

C

4、二叉树的遍历

以上图举例,树的遍历如何实现。

(1)二叉树遍历方式

  • 前序遍历:EACBDGF 从根节点开始,先左孩子再右孩子。

  • 中序遍历:ABCDEFG

  • 后序遍历:BDCAFGE

  • 层次遍历:EAGCFBD

(2)前序遍历代码实现

在二叉树代码实现的基础代码上,增加以下代码,以下代码为前序遍历主代码。

# 根节点
root = e

# 前序遍历
def pre_order(root):
    if root:   # root不为空
        print(root.data, end = ',')
        pre_order(root.lchild)  # 访问左孩子
        pre_order(root.rchild)  # 访问右孩子

pre_order(e) # 从e开始前序遍历

输出结果

E,A,C,B,D,G,F,

(3)中序遍历代码实现

中序遍历可以理解为将树结构“拍扁”,与前序遍历的区别仅在print打印的位置不同。

# 中序遍历
def in_order(root):
    if root:  # root不为空,递归结束条件
        in_order(root.lchild) # 访问左孩子
        print(root.data, end = ',') # 打印本身
        in_order(root.rchild) # 访问右孩子

in_order(root) # 从e开始前序遍历

输出结果

A,B,C,D,E,G,F,

递归原理

s1.首先,运行E的左孩子所在的子树,打印E,再运行E的右孩子所在的子树。

s2.进入E的左孩子的子树,A没有左孩子,打印A,运行A的右孩子。

s3.进入A的右孩子的子树,先运行C的左孩子,打印C,运行C的右孩子。

s4.进入C的左孩子的子树,打印了B;进入C的右孩子的子树,打印了D。

s5,进入E的右孩子的子树,依旧同以上步骤,得到G和F。

(4)后序遍历

# 后序遍历
def post_order(root):
    if root: # root不为空,递归结束条件
        post_order(root.lchild) # 访问左孩子
        post_order(root.rchild) # 访问右孩子
        print(root.data, end = ',') # 打印本身

post_order(root) # 从e开始前序遍历

输出结果

B,D,C,A,F,G,E,

递归原理

运行的顺序从左往右,与中序遍历的原理类似。先运行左孩子所在子树,再运行右孩子所在子树,最后才打印本身。

(5)层次遍历

# 层次遍历——广度优先搜索
from collections import deque # 队列模块

def level_order(root):
    queue = deque() # 新建队列
    queue.append(root) # 根节点入队
    while len(queue) > 0:  # 队列不空
        node = queue.popleft() # 节点出队
        print(node.data, end = ',') # 得到节点的值
        if node.lchild: # 节点的左孩子存在
            queue.append(node.lchild) # 左孩子进入队列
        if node.rchild: # 节点的右孩子存在
            queue.append(node.rchild) # 右孩子入队

level_order(root)

输出结果

E,A,G,C,F,B,D,

代码实现原理

使用单向队列的性质,节点出队时,其对应的孩子节点入队。例如(以本节遍历二叉树为例):

  • [E]:根节点入队

  • E,[A,G]:E出队,对应的左孩子A和右孩子入队

  • E,A,[G,C]:A出队,A的右孩子C入队

  • E,A,G,[C,F]:G出队,G的右孩子F入队

  • E,A,G,C,[F,B,D]:C出队,C的左孩子B,右孩子D出队

  • E,A,G,C,F,[B,D]:F出队,F没有孩子节点

  • E,A,G,C,F,B,[D]:B出队,B没有孩子节点

  • E,A,G,C,F,B,D,[]:D出队,D没有孩子节点,队列为空,结束循环。

三、二叉搜索树

1、概念

二叉搜索树是一棵二叉树且满足性质:设x是二叉树的一个节点。如果y是x左子树的一个节点,那么y.key x.key;如果y是x右子树的一个节点,那么y.key x.key。

如下图为一棵二叉搜索树:

二叉搜索树的操作:查询、插入、删除

查询和插入的时间复杂度都为O(logn),删除操作较为复杂后面会具体分析。

2、二叉搜索树:插入

(1)递归实现插入

当插入值小于当前节点的值,当前节点的左孩子(左孩子子树)是插入值的节点;当插入值大于当前节点的值,当前节点的右孩子(右孩子子树)是插入值的节点;若该值插入的位置不存在节点或该值与当前节点值相同,则创建新的节点或覆盖该节点。

# 二叉搜索树的用递归写插入函数

class BiTreeNode(): # 二叉树节点
    def __init__(self, data) -> None: # 属性
        self.data = data # 树的值
        self.lchild = None # 左孩子
        self.rchild = None # 右孩子
        self.parent = None # 父节点

# 二叉搜索树 binary search tree
class BST():
    def __init__(self): # 创建空树
        self.root = None # 根节点为空

    # 递归插入
    def insert(self, node, val): # node是指二叉树中当前指向的节点,初始一般为根节点,val是指插入的值
        if not node or node.data == val:  # 空树或节点的值与插入的值相同
            node = BiTreeNode(val) # 创建一个节点插入到树中(最后一步)或者是插入的值的节点直接与原节点相重合
        
        elif val < node.data:  # 插入的值小于当前节点的值
            # 往当前节点的左边插,当前节点的也就往左孩子找
            node.lchild = self.insert(node.lchild,val) # 左孩子为根节点的子树上,node.lchild(当前点的左孩子) = node(插入的节点)
            node.lchild.parent = node  # 与父节点的连接
                    
        else:  # val > node.data
            node.rchild = self.insert(node.rchild,val) # 当前节点的右孩子是插入的节点
            node.rchild.parent = node  

        return node # 返回

    
    # 前序遍历
    def pre_order(self, root):
        if root:   # root不为空
            print(root.data, end = ',')
            self.pre_order(root.lchild)  # 访问左孩子
            self.pre_order(root.rchild)  # 访问右孩子


tree = BST() 
node = BiTreeNode(10) # 树的根节点
# 插入数值
tree.insert(node,5) 
tree.insert(node,19) 
tree.insert(node,8)
tree.insert(node,3)
tree.pre_order(node)

输出结果

10,5,3,8,19,

(2)普通方式实现插入

# 二叉搜索树普通办法写插入函数

class BiTreeNode(): # 二叉树节点
    def __init__(self, data) -> None: # 属性
        self.data = data # 树的值
        self.lchild = None # 左孩子
        self.rchild = None # 右孩子
        self.parent = None # 父节点

# 二叉搜索树 binary search tree
class BST():
    def __init__(self, li=None): # 创建树
        self.root = None # 根节点为空
        # 创建二叉搜索树
        if li: 
            for val in li:
                self.insert_no_dec(val) # 循环插入值


    def insert_no_dec(self,val): # 非递归
        p = self.root # 创建指针p,p起始指向根节点
        if not p: # p指向节点为空,空树,
            self.root = BiTreeNode(val)  # 创建根节点
            return 
        
        while True: # 循环
            if val < p.data: # 插入值小于p指向节点的值
                if p.lchild: # 左孩子节点存在
                    p = p.lchild # 指针移动至新的节点
                else: # 左孩子不存在
                    p.lchild = BiTreeNode(val) # 插入值
                    p.lchild.parent = p # 连接父节点
                    return  # 结束循环,返回
            
            elif val > p.data: # 插入值大于p指向节点的值
                if p.rchild:  # 右孩子存在
                    p = p.rchild # 指针移动至新节点
                else: # 右孩子不存在
                    p.rchild = BiTreeNode(val) # 插入值
                    p.rchild.parent = p # 连接父节点
                    return # 结束循环,返回
            else: # val == p.data
                return # 不用插入
            
    # 前序遍历
    def pre_order(self,root):
        if root:   # root不为空
            print(root.data, end = ',')
            self.pre_order(root.lchild)  # 访问左孩子
            self.pre_order(root.rchild)  # 访问右孩子

    # 中序遍历
    def in_order(self, root):
        if root:  # root不为空,递归结束条件
            self.in_order(root.lchild) # 访问左孩子
            print(root.data, end = ',') # 打印本身
            self.in_order(root.rchild) # 访问右孩子

    # 后序遍历
    def post_order(self, root):
        if root: # root不为空,递归结束条件
            self.post_order(root.lchild) # 访问左孩子
            self.post_order(root.rchild) # 访问右孩子
            print(root.data, end = ',') # 打印本身
    
tree = BST([4,6,7,9,2,1,3,5,8]) # 对象实例化

# 遍历二叉树
tree.pre_order(tree.root)
print("") 
tree.in_order(tree.root)
print("")
tree.post_order(tree.root)

输出结果:

4,2,1,3,6,5,7,9,8,
1,2,3,4,5,6,7,8,9,
1,3,2,5,8,9,7,6,4,

说明:中序遍历的二叉搜索树一定是升序输出

3、二叉搜索树:查询

查询函数的原理与插入函数的原理基本一致。

import random

class BiTreeNode(): # 二叉树节点
    def __init__(self, data) -> None: # 属性
        self.data = data # 树的值
        self.lchild = None # 左孩子
        self.rchild = None # 右孩子
        self.parent = None # 父节点

# 二叉搜索树 binary search tree
class BST():
    def __init__(self, li=None): # 创建树
        self.root = None # 根节点为空
        # 创建二叉搜索树
        if li: 
            for val in li:
                self.insert_no_dec(val) # 循环插入值

    def insert_no_dec(self,val): # 非递归插入
        p = self.root # 创建指针p,p起始指向根节点
        if not p: # p指向节点为空,空树,
            self.root = BiTreeNode(val)  # 创建根节点
            return 
        
        while True: # 循环
            if val < p.data: # 插入值小于p指向节点的值
                if p.lchild: # 左孩子节点存在
                    p = p.lchild # 指针移动至新的节点
                else: # 左孩子不存在
                    p.lchild = BiTreeNode(val) # 插入值
                    p.lchild.parent = p # 连接父节点
                    return  # 结束循环,返回
            
            elif val > p.data: # 插入值大于p指向节点的值
                if p.rchild:  # 右孩子存在
                    p = p.rchild # 指针移动至新节点
                else: # 右孩子不存在
                    p.rchild = BiTreeNode(val) # 插入值
                    p.rchild.parent = p # 连接父节点
                    return # 结束循环,返回
            else: # val == p.data
                return # 不用插入

    def query(self, node, val): # 递归写查询
        if not node: # 节点不存在
            return None # 返回none
        elif val > node.data: # 值大于当前节点的值,往右子树找
            node = self.query(node.rchild, val) # 变量node是返回的node的赋值
        elif val < node.data: # 值小于当前节点的值,往左子树找
            node = self.query(node.lchild, val) 
        else: # val == node.data
            node = node # 值相等时返回节点
        return node
    def query_no_rec(self, val): # 非递归查询
        p = self.root  # p指针初始指向根节点
        while p: # 不是空树
            if val < p.data: # 值小于当前节点,往左找
                p = p.lchild # p指针下移
            elif val > p.data: # 值大于当前节点,往右找
                p = p.rchild # p指针往右下移
            else: # val == p.data
                return p # 退出循环
         return None

li = list(range(0,10,2)) # 0-9的偶数
random.shuffle(li)
tree = BST(li) # 创建树
node = tree.root
# print(node.data)
print(tree.query(node, 5)) # 递归
print(tree.query_no_rec(4)) # 非递归

输出结果

None
<__main__.BiTreeNode object at 0x00000170A1C1C6A0>

4、二叉搜索树:删除

(1)删除操作原理

二叉搜索树的删除与双向链表的删除极为相似。

1)要删除的节点是叶子节点:直接删除。node.parent.lchild 或者 node.parent,rchild = None

2)要删除的节点只有一个孩子:将此节点的父亲与孩子连接,然后删除该节点。如果删除的节点是根节点,则需要调整子树节点的位置。

3)要删除的节点有两个孩子:将其右子树的值最小的节点(该节点最多有一个右孩子,也可能就是叶子节点),该点一定为右子树的各节点的最后一个左孩子,找到该节点并替换当前节点的值,再删除该接节点

(2)删除操作代码实现

# 二叉搜索树——删除
class BiTreeNode(): # 二叉树节点
    def __init__(self, data) -> None: # 属性
        self.data = data # 树的值
        self.lchild = None # 左孩子
        self.rchild = None # 右孩子
        self.parent = None # 父节点

# 二叉搜索树 binary search tree
class BST():
    def __init__(self, li=None): # 创建树
        self.root = None # 根节点为空
        # 创建二叉搜索树
        if li: 
            for val in li:
                self.insert_no_dec(val) # 循环插入值

    def insert_no_dec(self,val): # 非递归插入
        p = self.root # 创建指针p,p起始指向根节点
        if not p: # p指向节点为空,空树,
            self.root = BiTreeNode(val)  # 创建根节点
            return 
        
        while True: # 循环
            if val < p.data: # 插入值小于p指向节点的值
                if p.lchild: # 左孩子节点存在
                    p = p.lchild # 指针移动至新的节点
                else: # 左孩子不存在
                    p.lchild = BiTreeNode(val) # 插入值
                    p.lchild.parent = p # 连接父节点
                    return  # 结束循环,返回
            
            elif val > p.data: # 插入值大于p指向节点的值
                if p.rchild:  # 右孩子存在
                    p = p.rchild # 指针移动至新节点
                else: # 右孩子不存在
                    p.rchild = BiTreeNode(val) # 插入值
                    p.rchild.parent = p # 连接父节点
                    return # 结束循环,返回
            else: # val == p.data
                return # 不用插入

    def query(self, node, val): # 递归写查询
        if not node: # 节点不存在
            return None # 返回none
        elif val > node.data: # 值大于当前节点的值,往右子树找
            node = self.query(node.rchild, val) # 变量node是返回的node的赋值
        elif val < node.data: # 值小于当前节点的值,往左子树找
            node = self.query(node.lchild, val) 
        else: # val == node.data
            node = node # 值相等时返回节点
        return node
    def query_no_rec(self, val): # 非递归查询
        p = self.root  # p指针初始指向根节点
        while p: # 不是空树
            if val < p.data: # 值小于当前节点,往左找
                p = p.lchild # p指针下移
            elif val > p.data: # 值大于当前节点,往右找
                p = p.rchild # p指针往右下移
            else: # val == p.data
                return p # 退出循环
        return None
    # 中序遍历
    def in_order(self,root):
        if root:  # root不为空,递归结束条件
            self.in_order(root.lchild) # 访问左孩子
            print(root.data, end = ',') # 打印本身
            self.in_order(root.rchild) # 访问右孩子

    def __remove_node_1(self, node): # 情况1:叶子节点
        # 判断是否为根节点
        if not node.parent: 
            self.root = None  # 根节点为None,即删除根节点
        if node == node.parent.lchild: # node为左孩子
            node.parent.lchild = None
        else: # node为右孩子
            node.parent.rchild = None
    
    def __remove_node_21(self,node): # 情况2.1:只有一个左孩子
        if not node.parent: # 根节点
            self.root = node.lchild # 根节点为node的左孩子
            node.lchild.parent = None # 左孩子的父亲为空
        elif node == node.parent.lchild: # node是父亲的左孩子
            node.parent.lchild = node.lchild # node父亲的左孩子变为node的左孩子
            node.lchild.parent = node.parent # node左孩子的父亲变为node的父亲
        else: # node是父亲的右孩子
            node.parent.rchild = node.lchild # node父亲的右孩子变为node的左孩子
            node.lchild.parent = node.parent # node左孩子的父亲变为node的父亲
    
    def __remove_node_22(self,node): # 情况2.2:只有一个右孩子
        if not node.parent: # 根节点
            self.root = node.rchild # 根节点为node的右孩子
            node.rchild.parent = None # 根节点没有父节点
        elif node == node.parent.lchild: # node是父亲的左孩子
            node.parent.lchild = node.rchild # node父亲的左孩子变为node的右孩子
            node.rchild.parent = node.parent # node右孩子的父亲变为node的父亲
        else: # node为父亲的右孩子
            node.parent.rchild = node.rchild # node父亲的右孩子变为node的右孩子
            node.rchild.parent = node.parent # node右孩子的父亲变为node的父亲
    
    def delete(self,val): # 删除操作(合并)
        if self.root: # 不是空树
            node = self.query_no_rec(val)  # 找到该节点 这步错了
            if not node: # node不存在
                return False
            if not node.lchild and not node.rchild: # 叶子节点
                self.__remove_node_1(node) # 情况1
            elif not node.rchild: # node只有左孩子
                self.__remove_node_21(node)  # 情况2.1
            elif not node.lchild: # node只有右孩子
                self.__remove_node_22(node) # 情况2.2
            else: # 情况3 即有左孩子又有右孩子
                # 找min_node,右子树的最小节点
                min_node = node.rchild # min_node在右子树上
                while min_node.lchild: # 直到没有左孩子
                    min_node = min_node.lchild  # min_node一直往左孩子移动,寻找
                node.data = min_node.data # 互换两者的值
                # 删除min_node
                if min_node.rchild: # 只有右孩子
                    self.__remove_node_22(min_node)
                else: # min_node为叶子节点
                    self.__remove_node_1(min_node)

tree = BST([1,4,2,5,3,8,6,9,7])
tree.in_order(tree.root)
print("")

# 删除值
tree.delete(4)
tree.delete(8)
tree.in_order(tree.root)

结果输出

1,2,3,4,5,6,7,8,9,
1,2,3,5,6,7,9,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/10276.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类ChatGPT代码级解读:如何从零起步实现Transformer、llama/ChatGLM

前言 最近一直在做类ChatGPT项目的部署 微调&#xff0c;关注比较多的是两个&#xff1a;一个LLaMA&#xff0c;一个ChatGLM&#xff0c;会发现有不少模型是基于这两个模型去做微调的&#xff0c;说到微调&#xff0c;那具体怎么微调呢&#xff0c;因此又详细了解了一下微调代…

Vulnhub_Pylington

目录 一、信息收集 &#xff08;一&#xff09;端口服务探测 &#xff08;二&#xff09;目录扫描 二、漏洞挖掘 &#xff08;一&#xff09;robots敏感信息泄露 &#xff08;二&#xff09;python IDE沙箱绕过RCE 1. python敏感函数沙盒绕过 2. exec(__import_…

【ES】搜索结果处理RestClient查询文档

【ES】搜索结果处理&RestClient查询文档2.搜索结果处理2.1.排序2.1.1.普通字段排序2.1.2.地理坐标排序2.2.分页2.2.1.基本的分页2.2.2.深度分页问题2.2.3.小结2.3.高亮2.3.1.高亮原理2.3.2.实现高亮2.4.总结3.RestClient查询文档3.1.快速入门3.1.1.发起查询请求3.1.2.解析响…

Python做个猫狗识别系统,给人美心善的邻居

嗨害大家好鸭&#xff01;我是爱摸鱼的芝士❤ 宠物真的看着好治愈 谁不想有一只属于自己的乖乖宠物捏~ 这篇文章中我放弃了以往的model.fit()训练方法&#xff0c; 改用model.train_on_batch方法。 两种方法的比较&#xff1a; model.fit()&#xff1a;用起来十分简单&#…

Kubernetes 部署 StarRocks 集群

文章目录StarRocks简介系统架构图安装部署StarRocks手动部署通过 Docker部署使用 StarGo 部署管理通过 StarRocks Manager部署管理通过 Kubernetes部署工作原理逻辑图部署 StarRocks Operator部署 StarRocks 集群访问 StarRocks 集群集群内访问 StarRocks 集群集群外访问 StarR…

【案例实践】R语言多元数据统计分析在生态环境中的实践应用

查看原文>>>R语言生物群落分析绘图、多元统计分析、CMIP6、遥感碳储量、GEE林业、InVEST等 生态环境领域研究中常常面对众多的不同类型的数据或变量&#xff0c;当要同时分析多个因变量&#xff08;y&#xff09;时需要用到多元统计分析&#xff08;multivariate sta…

Spark----DataFrame和DataSet

Spark之DataFrame和DataSet 文章目录Spark之DataFrame和DataSetDataFrameDSL 语法创建DataFrame查看DataFrame的Schema信息只查看列数据的6种方式按照“age”分区&#xff0c;查看数据条数增加列withColumn修改列名withColumnRenamedRDD 转换为 DataFrameDataFrame 转换为 RDD转…

音质蓝牙耳机哪款好用?2023公认音质好的四款蓝牙耳机推荐

现如今&#xff0c;蓝牙耳机越来越受欢迎&#xff0c;不少人在听歌、追剧、甚至是玩游戏的时候都会戴着它。最近看到很多人问&#xff0c;音质蓝牙耳机哪款好用&#xff1f;针对这个问题&#xff0c;我来给大家推荐四款公认音质好的蓝牙耳机&#xff0c;一起来看看吧。 一、南…

算法笔记:Frechet距离度量

曲线之间相似性的度量&#xff0c;它考虑了沿曲线的点的位置和顺序 1 概念 1.1 直观理解 主人走路径A&#xff0c;狗走路径B&#xff0c;他们有不同的配速方案主人和狗各自走完这两条路径过程中所需要的最短狗绳长度 &#xff08;在某一种配速下需要的狗绳长度&#xff09;&a…

考研复试确认神操作!

终于进行到了研究生考试的尾声&#xff0c;但让考生感到无力吐槽的事情&#xff0c;却还在继续上演&#xff0c;比如苏科大&#xff0c;再比如中地大、苏大&#xff0c;三所学校的神操作&#xff0c;着实让无数考生忍不住调侃&#xff1a;原来考研不仅拼实力&#xff0c;还得拼…

你的APP内存还在暴增吗?试着用Bitmap管理下内存~

作者&#xff1a;layz4android 相信伙伴们在日常的开发中&#xff0c;一定对图片加载有所涉猎&#xff0c;而且对于图片加载现有的第三方库也很多&#xff0c;例如Glide、coil等&#xff0c;使用这些三方库我们好像就没有啥担忧的&#xff0c;他们内部的内存管理和缓存策略做的…

如何实现Chatgpt写文章(附chatgpt3.5免费接口)

申明&#xff1a;本次只是说一下实现思路&#xff0c;官方的接口以及如何实现方式&#xff0c;本文没有提及&#xff0c;这次只是一个思路&#xff0c;若想代替人工完成质量还差的很远&#xff0c;请审核大大放行 今天再次优化了代码&#xff0c;修复了一些bug&#xff0c;考虑…

VUE 学习笔记(一)开发环境搭建

1、Visual Studio Code安装及使用 下载地址官网&#xff1a;https://code.visualstudio.com/ 直接点击下载按钮即可&#xff0c;会根据系统自动下载合适的版本&#xff0c;无需自行选择。 2、VSCode 上安装&#xff1a;JavaScript Debugger 目前 Debugger for Chrome 已经处…

使用向量机(SVM)算法的推荐系统部署实现

包括3个模块&#xff1a;数据预处理、模型训练及保存、模型测试&#xff0c;下面分别给出各模块的功能介绍及相关代码。 数据集下载链接为https://www.aitechclub.com/data-detail? data_id29&#xff0c;停用词典下载链接为http://www.datasoldier.net/archives/636。 1.数…

232:vue+openlayers选择左右两部分的地图,不重复,横向卷帘

第232个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中自定义js实现横向卷帘。这个示例中从左右两个选择框中来选择不同的地图,做了不重复的处理,即同一个数组,两部分根据选择后的状态做disabled处理,避免重复选择。 直接复制下面的 vue+openlayers…

c语言—指针进阶

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ…

第13届蓝桥杯省赛真题剖析-2022年4月17日Scratch编程初中级组

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第122讲。 第13届蓝桥杯省赛举办了两次&#xff0c;这是2022年4月17日举行的第一次省赛&#xff0c;比赛仍然采取线上形…

ChatGPT技术原理、研究框架,应用实践及发展趋势(附166份报告)

​ 一、AI框架重要性日益突显&#xff0c;框架技术发展进入繁荣期&#xff0c;国内AI框架技术加速发展&#xff1a; 1、AI框架作为衔接数据和模型的重要桥梁&#xff0c;发展进入繁荣期&#xff0c;国内外框架功能及性能加速迭代&#xff1b; 2、Pytorch、Tensorflow占据AI框…

因果推断14--DRNet论文和代码学习

目录 论文介绍 代码实现 DRNet ReadMe 因果森林 论文介绍 因果推断3--DRNet&#xff08;个人笔记&#xff09;_万三豹的博客-CSDN博客 摘要&#xff1a;估计个体在不同程度的治疗暴露下的潜在反应&#xff0c;对于医疗保健、经济学和公共政策等几个重要领域具有很高的实…

GFD563A101 3BHE046836R0101

GFD563A101 3BHE046836R0101 ABB 7寸触摸屏 PP874K 3BSE069273R1 控制面板 原装进口 ABB 7寸触摸屏 PP874M 3BSE069279R1 黑色坚固 船用认证面板 ABB AC 800M PM865K01 处理器单元 3BSE031151R6 PLC库存 ABB AC 800M控制器模块 PM861AK01 3BSE018157R1 PM861A ABB AC 800PEC PC…
最新文章