Python实战开发及案例分析(11)—— b树

        B树(B-Tree)是一种自平衡的树数据结构,它允许高效地进行查找、插入、删除等操作,广泛应用于数据库和文件系统。B树的每个节点可以包含多个键,并且有多个子节点。B树的关键特点包括:

  • 每个节点可以有多个子节点(度数m)。
  • 每个节点存储至少ceil(m/2) - 1个键,最多m - 1个键。
  • 根节点可以存储少于ceil(m/2) - 1个键。
  • 所有叶子节点处于同一层次上。

案例分析:使用 Python 实现 B 树

Python 实现 B 树

class BTreeNode:
    def __init__(self, t, leaf=False):
        self.t = t  # 最小度数
        self.leaf = leaf  # 是否是叶节点
        self.keys = []  # 节点的键
        self.children = []  # 节点的子节点

class BTree:
    def __init__(self, t):
        self.root = BTreeNode(t, True)
        self.t = t  # 最小度数

    def search(self, k, node=None):
        if node is None:
            node = self.root

        # 找到第一个大于或等于k的键
        i = 0
        while i < len(node.keys) and k > node.keys[i]:
            i += 1

        if i < len(node.keys) and node.keys[i] == k:
            return node, i

        if node.leaf:
            return None

        return self.search(k, node.children[i])

    def insert(self, k):
        root = self.root
        if len(root.keys) == (2 * self.t) - 1:
            new_root = BTreeNode(self.t, False)
            new_root.children.append(self.root)
            self.split_child(new_root, 0)
            self.root = new_root
            self.insert_non_full(new_root, k)
        else:
            self.insert_non_full(root, k)

    def insert_non_full(self, node, k):
        i = len(node.keys) - 1

        if node.leaf:
            node.keys.append(None)
            while i >= 0 and k < node.keys[i]:
                node.keys[i + 1] = node.keys[i]
                i -= 1
            node.keys[i + 1] = k
        else:
            while i >= 0 and k < node.keys[i]:
                i -= 1
            i += 1
            if len(node.children[i].keys) == (2 * self.t) - 1:
                self.split_child(node, i)
                if k > node.keys[i]:
                    i += 1
            self.insert_non_full(node.children[i], k)

    def split_child(self, parent, i):
        t = self.t
        new_node = BTreeNode(t, parent.children[i].leaf)
        node_to_split = parent.children[i]
        parent.keys.insert(i, node_to_split.keys[t - 1])
        parent.children.insert(i + 1, new_node)
        new_node.keys = node_to_split.keys[t:t + t - 1]
        node_to_split.keys = node_to_split.keys[0:t - 1]

        if not node_to_split.leaf:
            new_node.children = node_to_split.children[t:t + t]
            node_to_split.children = node_to_split.children[0:t]

    def traverse(self, node=None):
        if node is None:
            node = self.root

        i = 0
        for i in range(len(node.keys)):
            if not node.leaf:
                self.traverse(node.children[i])
            print(node.keys[i], end=" ")

        if not node.leaf:
            self.traverse(node.children[i + 1])

    def delete(self, k):
        self._delete(self.root, k)

        if len(self.root.keys) == 0:
            if not self.root.leaf:
                self.root = self.root.children[0]
            else:
                self.root = None

    def _delete(self, node, k):
        t = self.t
        i = 0
        while i < len(node.keys) and k > node.keys[i]:
            i += 1

        if i < len(node.keys) and node.keys[i] == k:
            if node.leaf:
                node.keys.pop(i)
            else:
                self._delete_non_leaf(node, i)
        else:
            if node.leaf:
                print(f"Key {k} not found in the tree")
                return

            flag = (i == len(node.keys))

            if len(node.children[i].keys) < t:
                self._fill(node, i)

            if flag and i > len(node.keys):
                self._delete(node.children[i - 1], k)
            else:
                self._delete(node.children[i], k)

    def _delete_non_leaf(self, node, i):
        k = node.keys[i]
        t = self.t

        if len(node.children[i].keys) >= t:
            pred = self._get_pred(node, i)
            node.keys[i] = pred
            self._delete(node.children[i], pred)

        elif len(node.children[i + 1].keys) >= t:
            succ = self._get_succ(node, i)
            node.keys[i] = succ
            self._delete(node.children[i + 1], succ)

        else:
            self._merge(node, i)
            self._delete(node.children[i], k)

    def _get_pred(self, node, i):
        curr = node.children[i]
        while not curr.leaf:
            curr = curr.children[len(curr.keys)]
        return curr.keys[len(curr.keys) - 1]

    def _get_succ(self, node, i):
        curr = node.children[i + 1]
        while not curr.leaf:
            curr = curr.children[0]
        return curr.keys[0]

    def _fill(self, node, i):
        t = self.t

        if i != 0 and len(node.children[i - 1].keys) >= t:
            self._borrow_from_prev(node, i)
        elif i != len(node.children) - 1 and len(node.children[i + 1].keys) >= t:
            self._borrow_from_next(node, i)
        else:
            if i != len(node.children) - 1:
                self._merge(node, i)
            else:
                self._merge(node, i - 1)

    def _borrow_from_prev(self, node, i):
        child = node.children[i]
        sibling = node.children[i - 1]

        child.keys.insert(0, node.keys[i - 1])

        if not child.leaf:
            child.children.insert(0, sibling.children.pop())

        node.keys[i - 1] = sibling.keys.pop()

    def _borrow_from_next(self, node, i):
        child = node.children[i]
        sibling = node.children[i + 1]

        child.keys.append(node.keys[i])

        if not child.leaf:
            child.children.append(sibling.children.pop(0))

        node.keys[i] = sibling.keys.pop(0)

    def _merge(self, node, i):
        t = self.t
        child = node.children[i]
        sibling = node.children[i + 1]

        child.keys.append(node.keys.pop(i))

        child.keys.extend(sibling.keys)

        if not child.leaf:
            child.children.extend(sibling.children)

        node.children.pop(i + 1)

# 示例使用
btree = BTree(3)

elements = [8, 9, 10, 11, 15, 20, 17, 25, 30, 35, 40, 45]
for elem in elements:
    btree.insert(elem)

print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nDeleting 15...")
btree.delete(15)
print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nDeleting 30...")
btree.delete(30)
print("Traversal of the B-Tree:")
btree.traverse()

解释与总结

        在以上代码中,我们实现了一个简单的B树,支持查找、插入和删除操作。以下是每个部分的解释:

  1. BTreeNode类

    • 表示B树的节点,包含keyschildren列表。
  2. BTree类

    • 管理整个B树结构。
    • search:查找键是否存在。
    • insert:插入键。
    • split_child:当节点满时拆分节点。
    • delete:删除键。
    • traverse:遍历树的所有节点。
  3. 示例代码

    • 初始化一个B树实例,并进行一系列的插入、删除和遍历操作,展示B树的完整功能。

结论

        通过这个简单的实现,我们可以看到B树在查找、插入和删除操作上具有高效性,并且能够保持平衡。它适用于需要频繁读写数据的场景,如数据库和文件系统。

        继续深入探讨 B 树的应用和功能增强,我们可以实现以下功能:

  1. 查找功能:添加在树中查找某个键的详细方法。
  2. 打印功能:打印 B 树结构,方便理解树的结构。
  3. 增强的删除功能:实现删除任意节点的完整逻辑。

增强版 B 树代码

class BTreeNode:
    def __init__(self, t, leaf=False):
        self.t = t  # 最小度数
        self.leaf = leaf  # 是否是叶节点
        self.keys = []  # 节点的键
        self.children = []  # 节点的子节点

    def is_full(self):
        return len(self.keys) == (2 * self.t) - 1

class BTree:
    def __init__(self, t):
        self.root = BTreeNode(t, True)
        self.t = t  # 最小度数

    def search(self, k, node=None):
        if node is None:
            node = self.root

        # 找到第一个大于或等于k的键
        i = 0
        while i < len(node.keys) and k > node.keys[i]:
            i += 1

        if i < len(node.keys) and node.keys[i] == k:
            return node, i

        if node.leaf:
            return None

        return self.search(k, node.children[i])

    def insert(self, k):
        root = self.root
        if root.is_full():
            new_root = BTreeNode(self.t, False)
            new_root.children.append(self.root)
            self.split_child(new_root, 0)
            self.root = new_root
            self.insert_non_full(new_root, k)
        else:
            self.insert_non_full(root, k)

    def insert_non_full(self, node, k):
        i = len(node.keys) - 1

        if node.leaf:
            node.keys.append(None)
            while i >= 0 and k < node.keys[i]:
                node.keys[i + 1] = node.keys[i]
                i -= 1
            node.keys[i + 1] = k
        else:
            while i >= 0 and k < node.keys[i]:
                i -= 1
            i += 1
            if node.children[i].is_full():
                self.split_child(node, i)
                if k > node.keys[i]:
                    i += 1
            self.insert_non_full(node.children[i], k)

    def split_child(self, parent, i):
        t = self.t
        new_node = BTreeNode(t, parent.children[i].leaf)
        node_to_split = parent.children[i]
        parent.keys.insert(i, node_to_split.keys[t - 1])
        parent.children.insert(i + 1, new_node)
        new_node.keys = node_to_split.keys[t:t + t - 1]
        node_to_split.keys = node_to_split.keys[0:t - 1]

        if not node_to_split.leaf:
            new_node.children = node_to_split.children[t:t + t]
            node_to_split.children = node_to_split.children[0:t]

    def traverse(self, node=None, depth=0):
        if node is None:
            node = self.root

        print(" " * 4 * depth + "Node:", node.keys)
        i = 0
        for i in range(len(node.keys)):
            if not node.leaf:
                self.traverse(node.children[i], depth + 1)
        if not node.leaf:
            self.traverse(node.children[i + 1], depth + 1)

    def delete(self, k):
        self._delete(self.root, k)

        if len(self.root.keys) == 0:
            if not self.root.leaf:
                self.root = self.root.children[0]
            else:
                self.root = None

    def _delete(self, node, k):
        t = self.t
        i = 0
        while i < len(node.keys) and k > node.keys[i]:
            i += 1

        if i < len(node.keys) and node.keys[i] == k:
            if node.leaf:
                node.keys.pop(i)
            else:
                self._delete_non_leaf(node, i)
        else:
            if node.leaf:
                print(f"Key {k} not found in the tree")
                return

            flag = (i == len(node.keys))

            if len(node.children[i].keys) < t:
                self._fill(node, i)

            if flag and i > len(node.keys):
                self._delete(node.children[i - 1], k)
            else:
                self._delete(node.children[i], k)

    def _delete_non_leaf(self, node, i):
        k = node.keys[i]
        t = self.t

        if len(node.children[i].keys) >= t:
            pred = self._get_pred(node, i)
            node.keys[i] = pred
            self._delete(node.children[i], pred)

        elif len(node.children[i + 1].keys) >= t:
            succ = self._get_succ(node, i)
            node.keys[i] = succ
            self._delete(node.children[i + 1], succ)

        else:
            self._merge(node, i)
            self._delete(node.children[i], k)

    def _get_pred(self, node, i):
        curr = node.children[i]
        while not curr.leaf:
            curr = curr.children[len(curr.keys)]
        return curr.keys[len(curr.keys) - 1]

    def _get_succ(self, node, i):
        curr = node.children[i + 1]
        while not curr.leaf:
            curr = curr.children[0]
        return curr.keys[0]

    def _fill(self, node, i):
        t = self.t

        if i != 0 and len(node.children[i - 1].keys) >= t:
            self._borrow_from_prev(node, i)
        elif i != len(node.children) - 1 and len(node.children[i + 1].keys) >= t:
            self._borrow_from_next(node, i)
        else:
            if i != len(node.children) - 1:
                self._merge(node, i)
            else:
                self._merge(node, i - 1)

    def _borrow_from_prev(self, node, i):
        child = node.children[i]
        sibling = node.children[i - 1]

        child.keys.insert(0, node.keys[i - 1])

        if not child.leaf:
            child.children.insert(0, sibling.children.pop())

        node.keys[i - 1] = sibling.keys.pop()

    def _borrow_from_next(self, node, i):
        child = node.children[i]
        sibling = node.children[i + 1]

        child.keys.append(node.keys[i])

        if not child.leaf:
            child.children.append(sibling.children.pop(0))

        node.keys[i] = sibling.keys.pop(0)

    def _merge(self, node, i):
        t = self.t
        child = node.children[i]
        sibling = node.children[i + 1]

        child.keys.append(node.keys.pop(i))

        child.keys.extend(sibling.keys)

        if not child.leaf:
            child.children.extend(sibling.children)

        node.children.pop(i + 1)

# 示例使用
btree = BTree(3)

elements = [8, 9, 10, 11, 15, 20, 17, 25, 30, 35, 40, 45]
for elem in elements:
    btree.insert(elem)

print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nDeleting 15...")
btree.delete(15)
print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nDeleting 30...")
btree.delete(30)
print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nSearching for 20...")
result = btree.search(20)
if result:
    node, idx = result
    print(f"Found key 20 in node with keys: {node.keys}")
else:
    print("Key 20 not found in the B-Tree.")

解释与总结

  1. 增强的打印功能

    • traverse:增强了打印逻辑,包含深度信息以可视化树结构。
  2. 搜索功能

    • search:用于在树中查找键的位置。
  3. 完整的删除功能

    • _delete_non_leaf:删除非叶节点的键。
    • _get_pred_get_succ:获取前驱和后继键。
    • _fill_borrow_from_prev_borrow_from_next_merge:在删除操作中保持 B 树平衡。

结论

通过完整的B树实现,包含搜索、插入、删除和遍历功能,使得 B 树在数据库和文件系统等高效查找领域具备广泛的应用。

        让我们继续增强和完善 B 树的功能,并增加更多的示例应用。以下是进一步的增强:

  1. 打印更详细的 B 树结构:可视化显示每个节点的层次和子节点的键。
  2. 修改树的最小度数(t:允许动态调整最小度数。
  3. 统计功能:包括计算树的高度和统计总节点数、总键数等。

增强版 B 树代码

class BTreeNode:
    def __init__(self, t, leaf=False):
        self.t = t  # 最小度数
        self.leaf = leaf  # 是否是叶节点
        self.keys = []  # 节点的键
        self.children = []  # 节点的子节点

    def is_full(self):
        return len(self.keys) == (2 * self.t) - 1

class BTree:
    def __init__(self, t):
        self.root = BTreeNode(t, True)
        self.t = t  # 最小度数

    def search(self, k, node=None):
        if node is None:
            node = self.root

        # 找到第一个大于或等于k的键
        i = 0
        while i < len(node.keys) and k > node.keys[i]:
            i += 1

        if i < len(node.keys) and node.keys[i] == k:
            return node, i

        if node.leaf:
            return None

        return self.search(k, node.children[i])

    def insert(self, k):
        root = self.root
        if root.is_full():
            new_root = BTreeNode(self.t, False)
            new_root.children.append(self.root)
            self.split_child(new_root, 0)
            self.root = new_root
            self.insert_non_full(new_root, k)
        else:
            self.insert_non_full(root, k)

    def insert_non_full(self, node, k):
        i = len(node.keys) - 1

        if node.leaf:
            node.keys.append(None)
            while i >= 0 and k < node.keys[i]:
                node.keys[i + 1] = node.keys[i]
                i -= 1
            node.keys[i + 1] = k
        else:
            while i >= 0 and k < node.keys[i]:
                i -= 1
            i += 1
            if node.children[i].is_full():
                self.split_child(node, i)
                if k > node.keys[i]:
                    i += 1
            self.insert_non_full(node.children[i], k)

    def split_child(self, parent, i):
        t = self.t
        new_node = BTreeNode(t, parent.children[i].leaf)
        node_to_split = parent.children[i]
        parent.keys.insert(i, node_to_split.keys[t - 1])
        parent.children.insert(i + 1, new_node)
        new_node.keys = node_to_split.keys[t:t + t - 1]
        node_to_split.keys = node_to_split.keys[0:t - 1]

        if not node_to_split.leaf:
            new_node.children = node_to_split.children[t:t + t]
            node_to_split.children = node_to_split.children[0:t]

    def traverse(self, node=None, depth=0):
        if node is None:
            node = self.root

        print(" " * 4 * depth + f"Level {depth}: {node.keys}")
        i = 0
        for i in range(len(node.keys)):
            if not node.leaf:
                self.traverse(node.children[i], depth + 1)
        if not node.leaf:
            self.traverse(node.children[i + 1], depth + 1)

    def delete(self, k):
        self._delete(self.root, k)

        if len(self.root.keys) == 0:
            if not self.root.leaf:
                self.root = self.root.children[0]
            else:
                self.root = None

    def _delete(self, node, k):
        t = self.t
        i = 0
        while i < len(node.keys) and k > node.keys[i]:
            i += 1

        if i < len(node.keys) and node.keys[i] == k:
            if node.leaf:
                node.keys.pop(i)
            else:
                self._delete_non_leaf(node, i)
        else:
            if node.leaf:
                print(f"Key {k} not found in the tree")
                return

            flag = (i == len(node.keys))

            if len(node.children[i].keys) < t:
                self._fill(node, i)

            if flag and i > len(node.keys):
                self._delete(node.children[i - 1], k)
            else:
                self._delete(node.children[i], k)

    def _delete_non_leaf(self, node, i):
        k = node.keys[i]
        t = self.t

        if len(node.children[i].keys) >= t:
            pred = self._get_pred(node, i)
            node.keys[i] = pred
            self._delete(node.children[i], pred)

        elif len(node.children[i + 1].keys) >= t:
            succ = self._get_succ(node, i)
            node.keys[i] = succ
            self._delete(node.children[i + 1], succ)

        else:
            self._merge(node, i)
            self._delete(node.children[i], k)

    def _get_pred(self, node, i):
        curr = node.children[i]
        while not curr.leaf:
            curr = curr.children[len(curr.keys)]
        return curr.keys[len(curr.keys) - 1]

    def _get_succ(self, node, i):
        curr = node.children[i + 1]
        while not curr.leaf:
            curr = curr.children[0]
        return curr.keys[0]

    def _fill(self, node, i):
        t = self.t

        if i != 0 and len(node.children[i - 1].keys) >= t:
            self._borrow_from_prev(node, i)
        elif i != len(node.children) - 1 and len(node.children[i + 1].keys) >= t:
            self._borrow_from_next(node, i)
        else:
            if i != len(node.children) - 1:
                self._merge(node, i)
            else:
                self._merge(node, i - 1)

    def _borrow_from_prev(self, node, i):
        child = node.children[i]
        sibling = node.children[i - 1]

        child.keys.insert(0, node.keys[i - 1])

        if not child.leaf:
            child.children.insert(0, sibling.children.pop())

        node.keys[i - 1] = sibling.keys.pop()

    def _borrow_from_next(self, node, i):
        child = node.children[i]
        sibling = node.children[i + 1]

        child.keys.append(node.keys[i])

        if not child.leaf:
            child.children.append(sibling.children.pop(0))

        node.keys[i] = sibling.keys.pop(0)

    def _merge(self, node, i):
        t = self.t
        child = node.children[i]
        sibling = node.children[i + 1]

        child.keys.append(node.keys.pop(i))

        child.keys.extend(sibling.keys)

        if not child.leaf:
            child.children.extend(sibling.children)

        node.children.pop(i + 1)

    def get_height(self, node=None):
        if node is None:
            node = self.root

        if node.leaf:
            return 1
        return 1 + self.get_height(node.children[0])

    def count_nodes_and_keys(self, node=None):
        if node is None:
            node = self.root

        node_count = 1
        key_count = len(node.keys)

        if not node.leaf:
            for child in node.children:
                child_node_count, child_key_count = self.count_nodes_and_keys(child)
                node_count += child_node_count
                key_count += child_key_count

        return node_count, key_count

# 示例使用
btree = BTree(3)

elements = [8, 9, 10, 11, 15, 20, 17, 25, 30, 35, 40, 45]
for elem in elements:
    btree.insert(elem)

print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nDeleting 15...")
btree.delete(15)
print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nDeleting 30...")
btree.delete(30)
print("Traversal of the B-Tree:")
btree.traverse()

print("\n\nSearching for 20...")
result = btree.search(20)
if result:
    node, idx = result
    print(f"Found key 20 in node with keys: {node.keys}")
else:
    print("Key 20 not found in the B-Tree.")

print("\n\nStatistics:")
height = btree.get_height()
nodes, keys = btree.count_nodes_and_keys()
print(f"Height of the B-Tree: {height}")
print(f"Total nodes in the B-Tree: {nodes}")
print(f"Total keys in the B-Tree: {keys}")

解释与总结

  1. B 树层次打印

    • traverse 方法打印每一层的键值。
  2. 统计功能

    • get_height:计算树的高度。
    • count_nodes_and_keys:计算节点和键的总数。
  3. 完整的插入与删除功能

    • insertdelete 操作保持树的平衡性。

结论

        通过实现增强版的 B 树功能,我们可以看到这是一种高效的多路搜索树结构,适合用于数据库索引和文件系统管理。利用这些功能增强,B 树的应用前景更加广阔。

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

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

相关文章

TCP经典异常问题探讨与解决

作者&#xff1a;kernelxing TCP的经典异常问题无非就是丢包和连接中断&#xff0c;在这里我打算与各位聊一聊TCP的RST到底是什么&#xff1f;现网中的RST问题有哪些模样&#xff1f;我们如何去应对、解决&#xff1f;本文将从RST原理、排查手段、现网痛难点案例三个板块自上而…

【Linux系列】file命令

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

yum仓库和NFS网络共享服务

一、yum 1.1yum的定义 yum是一个基于RPM包&#xff0c;构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。解决了日常工作中的大量查找安装依赖包的时间 为什么会有依赖关系的发生 因为linux本身就是以系统简洁为自身优势&#xff0c;所以在安装操作系统的时…

DB-GPT: Empowering Database Interactions with Private Large Language Models 导读

本文介绍了一种名为DB-GPT的新技术&#xff0c;它将大型语言模型&#xff08;LLM&#xff09;与传统数据库系统相结合&#xff0c;提高了用户使用数据库的体验和便利性。DB-GPT可以理解自然语言查询、提供上下文感知的回答&#xff0c;并生成高准确度的复杂SQL查询&#xff0c;…

搭建父模块和工具子模块

第一章 项目父模块搭建 1.1 nancal-idsa 作为所有工程的父工程&#xff0c;用于管理项目的所有依赖版本。 1.2 指定 pom 类型模块&#xff0c;删除 src 目录&#xff0c;点击Reload project 1.3 添加依赖 pom.xml <parent> <groupId>org.springframework.…

鸿蒙内核源码分析(中断管理篇) | 江湖从此不再怕中断

关于中断部分系列篇将用三篇详细说明整个过程. 中断概念篇 中断概念很多&#xff0c;比如中断控制器&#xff0c;中断源&#xff0c;中断向量&#xff0c;中断共享&#xff0c;中断处理程序等等.本篇做一次整理.先了解透概念才好理解中断过程.用海公公打比方说明白中断各个概念…

端口被其他进程占用:OSError: [Errno 98] Address already in use

一、问题描述 错误提示端口号正在被使用 二、解决办法 1.使用 lsof 命令&#xff0c;列出所有正在监听&#xff08;即被绑定&#xff09;的网络连接&#xff0c;包括它们所使用的端口号 sudo lsof -i -P -n | grep LISTEN 2.解绑被绑定的端口号 根据 netstat 或 lsof 命令…

基于OpenPCDet框架进行Pointpillars算法环境搭建并基于TensorRT和ROS部署

文章目录 参考链接1.创建虚拟环境2.安装OpenDet3.安装用于模型转换的库4.数据集转换5.模型训练6.部署安装tensorrt模型转换 编译ROS工程结果报错梳理【报错1】【报错2】【报错3】【报错4】【报错5】 参考链接 基于OpenDet进行训练&#xff0c;基于tensorrt-8.5进行部署并移植到…

常见错误以及如何纠正它们

团队和关键结果目标 (OKR) 之间的关系是深刻且至关重要的。总而言之&#xff0c;一切都应该是相互关联的。正如《团队的智慧》一书中所强调的&#xff1a; 在团队中&#xff0c;没有什么比每个成员对共同目标和一组相关绩效目标的承诺更重要的了&#xff0c;而团队对此负有共同…

经常发文章的你是否想过定时发布是咋实现的?

前言 可乐他们团队最近在做一个文章社区平台,由于人手不够,前后端都是由前端同学来写。后端使用 nest 来实现。 某一天周五下午,可乐正在快乐摸鱼,想到周末即将来临,十分开心。然而,产品突然找到了他,说道:可乐,我们要做一个文章定时发布功能。 现在我先为你解释一…

值得收藏!修复Windows 10/11中找不到输出或输入设备的五种方法

序言 这篇文章主要关注处理声音输出/输入设备未发现的问题。它提供了许多可行的方法,帮助了许多Windows用户。阅读以下内容以找到你的解决方案。 最近,我将Windows 10更新到21H2,发现我的音频无法工作。当我把鼠标放在任务栏上的声音图标(上面有一个十字图标)上时,它会…

市面上好用的AI工具有哪些?

市面上的AI工具数不胜数&#xff0c;选择合适自己的AI工具则需要考虑自己的需求&#xff0c;看是否能满足的使用需求。那么市面上又有哪些好用的AI工具呢&#xff1f; 泰迪智能科技拥有简单易用的大数据挖掘建模平台&#xff0c;能够让数据创造更大的价值。 功能板块&…

基于Springboot的校园新闻管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园新闻管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

Android 巧用putBinder方法传递大文件

使用Intent传递数据大家都知道&#xff0c;但是如果你使用Intent传递大于1Mb的数据时&#xff0c;就一定会报如下的错误&#xff1a; Caused by: android.os.TransactionTooLargeException: data parcel size 1049112 bytes 就是说你的传输数据太大了&#xff0c;当前的大小达…

Rust 解决循环引用

导航 循环引用一、现象二、解决 循环引用 循环引用出现的一个场景就是你指向我&#xff0c;我指向你&#xff0c;导致程序崩溃 解决方式可以通过弱指针&#xff0c;而Rust中的弱指针就是Weak 在Rc中&#xff0c;可以实现&#xff0c;对一个变量&#xff0c;持有多个不可变引…

FSC森林认证是什么?

FSC森林认证&#xff0c;又称木材认证&#xff0c;是一种运用市场机制来促进森林可持续经营&#xff0c;实现生态、社会和经济目标的工具。FSC森林认证包括森林经营认证&#xff08;Forest Management, FM&#xff09;和产销监管链认证&#xff08;Chain of Custody, COC&#…

人大金仓V8R6迁移mysql8.0

人大金仓数据库迁移mysql mysql版本&#xff1a;mysql 8.0.22 人大金仓版本;KingbaseES V008R006C008B0014 on x64 打开数据迁移工具 等待执行完成后使用命令窗口中提示的地址在浏览器中打开&#xff1a; 登录。此处登录不用修改任何信息&#xff0c;点击登录即可 新建源数…

初识Node.js-认识node(安装Node.js环境配置)

目录 一、node介绍 1.概念和特点 2.核心功能 3.应用场景 二、Node初使用 1.安装node配置 windows上安Node.js 1.windows安装包&#xff08;.msi&#xff09; 2、Windows 二进制文件 (.exe)安装 Linux 上安装 Node.js 直接使用已编译好的包 Ubuntu 源码安装 Node.js …

⚡REST 和 SOAP 协议有什么区别?

原文链接&#xff1a;https://document360.com/blog/rest-vs-soap/ API 是应用程序编程接口&#xff08;Application Programming Interface&#xff09;的缩写。API 规定了不同的软件组件应如何以编程方式进行交互和通信。 最常见的 API 类型就是 Web API。网络应用&#xff…

自学错误合集--项目打包报错,运行报错持续更新中

java后端自学错误总结 一.项目打包报错2.项目打包之后运行报错 二.项目运行报错 一.项目打包报错 javac: &#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ļ&#xfffd;: E:\xx\xx\xx\docer-xx\src\main\java\xx\xx\xx\xx\xx\xx.java &#xfffd;&#xff…
最新文章