C++ -- 红黑树的基本操作

目录

摘要

基本规则

基本操作

利用Graphviz 库

总结


摘要

红黑树是一种自平衡的二叉搜索树,它在插入和删除节点时,通过颜色和旋转操作保持树的平衡,确保插入、删除和查找的时间复杂度都是 (O(log n))。红黑树的每个节点都有一个颜色属性,红色或黑色。通过一些规则,红黑树保持了相对平衡,使得最长路径长度不会超过最短路径长度的两倍。

基本规则

1. 每个节点不是红色就是黑色。
2. 根节点是黑色。
3. 每个叶子节点(NIL节点)是黑色。
4. 如果一个节点是红色的,则它的两个子节点都是黑色的(从每个叶子到根的所有路径上不能有两个连续的红色节点)。
5. 从任一节点到其每个叶子的所有简单路径都包含相同数量的黑色节点。

基本操作

插入操作

#include <iostream>

enum Color { RED, BLACK };

struct Node {
    int data;
    Color color;
    Node *left, *right, *parent;

    Node(int data) : data(data), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};

class RedBlackTree {
public:
    RedBlackTree() : root(nullptr) {}

    void insert(int data) {
        Node* newNode = new Node(data);
        root = bstInsert(root, newNode);
        fixViolation(newNode);
    }

    void inorder() { inorderHelper(root); }

private:
    Node* root;

    Node* bstInsert(Node* root, Node* node) {
        if (root == nullptr) return node;
        if (node->data < root->data) {
            root->left = bstInsert(root->left, node);
            root->left->parent = root;
        } else if (node->data > root->data) {
            root->right = bstInsert(root->right, node);
            root->right->parent = root;
        }
        return root;
    }

    void fixViolation(Node* node) {
        Node* parent = nullptr;
        Node* grandParent = nullptr;

        while (node != root && node->color == RED && node->parent->color == RED) {
            parent = node->parent;
            grandParent = parent->parent;

            if (parent == grandParent->left) {
                Node* uncle = grandParent->right;

                if (uncle != nullptr && uncle->color == RED) {
                    grandParent->color = RED;
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    node = grandParent;
                } else {
                    if (node == parent->right) {
                        rotateLeft(parent);
                        node = parent;
                        parent = node->parent;
                    }
                    rotateRight(grandParent);
                    std::swap(parent->color, grandParent->color);
                    node = parent;
                }
            } else {
                Node* uncle = grandParent->left;

                if (uncle != nullptr && uncle->color == RED) {
                    grandParent->color = RED;
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    node = grandParent;
                } else {
                    if (node == parent->left) {
                        rotateRight(parent);
                        node = parent;
                        parent = node->parent;
                    }
                    rotateLeft(grandParent);
                    std::swap(parent->color, grandParent->color);
                    node = parent;
                }
            }
        }
        root->color = BLACK;
    }

    void rotateLeft(Node* node) {
        Node* rightNode = node->right;
        node->right = rightNode->left;

        if (node->right != nullptr) node->right->parent = node;
        rightNode->parent = node->parent;

        if (node->parent == nullptr) root = rightNode;
        else if (node == node->parent->left) node->parent->left = rightNode;
        else node->parent->right = rightNode;

        rightNode->left = node;
        node->parent = rightNode;
    }

    void rotateRight(Node* node) {
        Node* leftNode = node->left;
        node->left = leftNode->right;

        if (node->left != nullptr) node->left->parent = node;
        leftNode->parent = node->parent;

        if (node->parent == nullptr) root = leftNode;
        else if (node == node->parent->left) node->parent->left = leftNode;
        else node->parent->right = leftNode;

        leftNode->right = node;
        node->parent = leftNode;
    }

    void inorderHelper(Node* root) {
        if (root == nullptr) return;
        inorderHelper(root->left);
        std::cout << root->data << " ";
        inorderHelper(root->right);
    }
};

int main() {
    RedBlackTree tree;
    tree.insert(10);
    tree.insert(20);
    tree.insert(30);
    tree.insert(15);

    std::cout << "Inorder traversal of the constructed tree is ";
    tree.inorder();
    std::cout << std::endl;

    return 0;
}
// Output
Inorder traversal of the constructed tree is 10 15 20 30

     20(B)
   /    \
10(B)  30(B)
   \
   15(R)

插入和删除操作

#include <iostream>
#include <queue>

enum Color { RED, BLACK };

struct Node {
    int data;
    Color color;
    Node *left, *right, *parent;

    Node(int data) : data(data), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}

    Node* sibling() {
        if (parent == nullptr) return nullptr;
        return this == parent->left ? parent->right : parent->left;
    }

    bool hasRedChild() {
        return (left != nullptr && left->color == RED) || (right != nullptr && right->color == RED);
    }
};

class RedBlackTree {
public:
    Node* root;

    RedBlackTree() : root(nullptr) {}

    void insert(int data) {
        Node* newNode = new Node(data);
        root = bstInsert(root, newNode);
        fixViolation(newNode);
    }

    void deleteNode(int data) {
        Node* nodeToDelete = search(root, data);
        if (nodeToDelete == nullptr) return;
        deleteBSTNode(nodeToDelete);
    }

    void inorder() { inorderHelper(root); }

    void levelOrder() {
        if (root == nullptr) return;
        std::queue<Node*> q;
        q.push(root);

        while (!q.empty()) {
            Node* temp = q.front();
            std::cout << temp->data << " ";
            q.pop();

            if (temp->left != nullptr)
                q.push(temp->left);

            if (temp->right != nullptr)
                q.push(temp->right);
        }
    }

private:
    Node* bstInsert(Node* root, Node* node) {
        if (root == nullptr) return node;
        if (node->data < root->data) {
            root->left = bstInsert(root->left, node);
            root->left->parent = root;
        } else if (node->data > root->data) {
            root->right = bstInsert(root->right, node);
            root->right->parent = root;
        }
        return root;
    }

    Node* search(Node* root, int data) {
        if (root == nullptr || root->data == data) return root;
        return data < root->data ? search(root->left, data) : search(root->right, data);
    }

    void deleteBSTNode(Node* node) {
        Node* replacement = BSTreplace(node);
        bool bothBlack = ((replacement == nullptr || replacement->color == BLACK) && (node->color == BLACK));
        Node* parent = node->parent;

        if (replacement == nullptr) {
            if (node == root) {
                root = nullptr;
            } else {
                if (bothBlack) {
                    fixDoubleBlack(node);
                } else {
                    if (node->sibling() != nullptr) node->sibling()->color = RED;
                }
                if (node == node->parent->left) {
                    node->parent->left = nullptr;
                } else {
                    node->parent->right = nullptr;
                }
            }
            delete node;
            return;
        }

        if (node->left == nullptr || node->right == nullptr) {
            if (node == root) {
                node->data = replacement->data;
                node->left = node->right = nullptr;
                delete replacement;
            } else {
                if (node == node->parent->left) {
                    parent->left = replacement;
                } else {
                    parent->right = replacement;
                }
                delete node;
                replacement->parent = parent;
                if (bothBlack) {
                    fixDoubleBlack(replacement);
                } else {
                    replacement->color = BLACK;
                }
            }
            return;
        }

        std::swap(node->data, replacement->data);
        deleteBSTNode(replacement);
    }

    Node* BSTreplace(Node* node) {
        if (node->left != nullptr && node->right != nullptr) return successor(node->right);
        if (node->left == nullptr && node->right == nullptr) return nullptr;
        return node->left != nullptr ? node->left : node->right;
    }

    Node* successor(Node* node) {
        Node* temp = node;
        while (temp->left != nullptr) temp = temp->left;
        return temp;
    }

    void fixViolation(Node* node) {
        Node* parent = nullptr;
        Node* grandParent = nullptr;

        while (node != root && node->color == RED && node->parent->color == RED) {
            parent = node->parent;
            grandParent = parent->parent;

            if (parent == grandParent->left) {
                Node* uncle = grandParent->right;

                if (uncle != nullptr && uncle->color == RED) {
                    grandParent->color = RED;
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    node = grandParent;
                } else {
                    if (node == parent->right) {
                        rotateLeft(parent);
                        node = parent;
                        parent = node->parent;
                    }
                    rotateRight(grandParent);
                    std::swap(parent->color, grandParent->color);
                    node = parent;
                }
            } else {
                Node* uncle = grandParent->left;

                if (uncle != nullptr && uncle->color == RED) {
                    grandParent->color = RED;
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    node = grandParent;
                } else {
                    if (node == parent->left) {
                        rotateRight(parent);
                        node = parent;
                        parent = node->parent;
                    }
                    rotateLeft(grandParent);
                    std::swap(parent->color, grandParent->color);
                    node = parent;
                }
            }
        }
        root->color = BLACK;
    }

    void fixDoubleBlack(Node* node) {
        if (node == root) return;

        Node* sibling = node->sibling();
        Node* parent = node->parent;
        if (sibling == nullptr) {
            fixDoubleBlack(parent);
        } else {
            if (sibling->color == RED) {
                parent->color = RED;
                sibling->color = BLACK;
                if (sibling == parent->left) {
                    rotateRight(parent);
                } else {
                    rotateLeft(parent);
                }
                fixDoubleBlack(node);
            } else {
                if (sibling->hasRedChild()) {
                    if (sibling->left != nullptr && sibling->left->color == RED) {
                        if (sibling == parent->left) {
                            sibling->left->color = sibling->color;
                            sibling->color = parent->color;
                            rotateRight(parent);
                        } else {
                            sibling->left->color = parent->color;
                            rotateRight(sibling);
                            rotateLeft(parent);
                        }
                    } else {
                        if (sibling == parent->left) {
                            sibling->right->color = parent->color;
                            rotateLeft(sibling);
                            rotateRight(parent);
                        } else {
                            sibling->right->color = sibling->color;
                            sibling->color = parent->color;
                            rotateLeft(parent);
                        }
                    }
                    parent->color = BLACK;
                } else {
                    sibling->color = RED;
                    if (parent->color == BLACK) {
                        fixDoubleBlack(parent);
                    } else {
                        parent->color = BLACK;
                    }
                }
            }
        }
    }

    void rotateLeft(Node* node) {
        Node* rightNode = node->right;
        node->right = rightNode->left;

        if (node->right != nullptr) node->right->parent = node;
        rightNode->parent = node->parent;

        if (node->parent == nullptr) root = rightNode;
        else if (node == node->parent->left) node->parent->left = rightNode;
        else node->parent->right = rightNode;

        rightNode->left = node;
        node->parent = rightNode;
    }

    void rotateRight(Node* node) {
        Node* leftNode = node->left;
        node->left = leftNode->right;

        if (node->left != nullptr) node->left->parent = node;
        leftNode->parent = node->parent;

        if (node->parent == nullptr) root = leftNode;
        else if (node == node->parent->left) node->parent->left = leftNode;
        else node->parent->right = leftNode;

        leftNode->right = node;
        node->parent = leftNode;
    }

    void inorderHelper(Node* root) {
        if (root == nullptr) return;
        inorderHelper(root->left);
        std::cout << root->data << " ";
        inorderHelper(root->right);
    }
};

int main() {
    RedBlackTree tree;
    tree.insert(10);
    tree.insert(20);
    tree.insert(30);
    tree.insert(15);
    tree.insert(25);
    tree.insert(5);

    std::cout << "Inorder traversal of the constructed tree is ";
    tree.inorder();
    std::cout << std::endl;

    tree.deleteNode(20);

    std::cout << "Inorder traversal after deleting 20 is ";
    tree.inorder();
    std::cout << std::endl;

    std::cout << "Level order traversal of the tree is ";
    tree.levelOrder();
    std::cout << std::endl;

    return 0;
}
// Output

Inorder traversal of the constructed tree is 5 10 15 20 25 30 
Inorder traversal after deleting 20 is 5 10 15 25 30 
Level order traversal of the tree is 15 10 30 5 25 


     15(B)
   /    \
10(B)  30(B)
 /     /
5(B)  25(R)

利用Graphviz 库

利用 Graphviz 库的图形化表示我们需要生成的红黑树。

Graphviz Online

#include <iostream>
#include <fstream>
#include <queue>

enum Color { RED, BLACK };

struct Node {
    int data;
    Color color;
    Node *left, *right, *parent;

    Node(int data) : data(data), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}

    Node* sibling() {
        if (parent == nullptr) return nullptr;
        return this == parent->left ? parent->right : parent->left;
    }

    bool hasRedChild() {
        return (left != nullptr && left->color == RED) || (right != nullptr && right->color == RED);
    }
};

class RedBlackTree {
public:
    Node* root;

    RedBlackTree() : root(nullptr) {}

    void insert(int data) {
        Node* newNode = new Node(data);
        root = bstInsert(root, newNode);
        fixViolation(newNode);
    }

    void deleteNode(int data) {
        Node* nodeToDelete = search(root, data);
        if (nodeToDelete == nullptr) return;
        deleteBSTNode(nodeToDelete);
    }

    void inorder() { inorderHelper(root); }

    void levelOrder() {
        if (root == nullptr) return;
        std::queue<Node*> q;
        q.push(root);

        while (!q.empty()) {
            Node* temp = q.front();
            std::cout << temp->data << " ";
            q.pop();

            if (temp->left != nullptr)
                q.push(temp->left);

            if (temp->right != nullptr)
                q.push(temp->right);
        }
    }

    void generateGraphviz(const std::string& filename) {
        std::ofstream file(filename);
        file << "digraph G {\n";
        if (root == nullptr) {
            file << "}\n";
            return;
        }
        generateGraphvizHelper(file, root);
        file << "}\n";
    }

private:
    Node* bstInsert(Node* root, Node* node) {
        if (root == nullptr) return node;
        if (node->data < root->data) {
            root->left = bstInsert(root->left, node);
            root->left->parent = root;
        } else if (node->data > root->data) {
            root->right = bstInsert(root->right, node);
            root->right->parent = root;
        }
        return root;
    }

    Node* search(Node* root, int data) {
        if (root == nullptr || root->data == data) return root;
        return data < root->data ? search(root->left, data) : search(root->right, data);
    }

    void deleteBSTNode(Node* node) {
        Node* replacement = BSTreplace(node);
        bool bothBlack = ((replacement == nullptr || replacement->color == BLACK) && (node->color == BLACK));
        Node* parent = node->parent;

        if (replacement == nullptr) {
            if (node == root) {
                root = nullptr;
            } else {
                if (bothBlack) {
                    fixDoubleBlack(node);
                } else {
                    if (node->sibling() != nullptr) node->sibling()->color = RED;
                }
                if (node == node->parent->left) {
                    node->parent->left = nullptr;
                } else {
                    node->parent->right = nullptr;
                }
            }
            delete node;
            return;
        }

        if (node->left == nullptr || node->right == nullptr) {
            if (node == root) {
                node->data = replacement->data;
                node->left = node->right = nullptr;
                delete replacement;
            } else {
                if (node == node->parent->left) {
                    parent->left = replacement;
                } else {
                    parent->right = replacement;
                }
                delete node;
                replacement->parent = parent;
                if (bothBlack) {
                    fixDoubleBlack(replacement);
                } else {
                    replacement->color = BLACK;
                }
            }
            return;
        }

        std::swap(node->data, replacement->data);
        deleteBSTNode(replacement);
    }

    Node* BSTreplace(Node* node) {
        if (node->left != nullptr && node->right != nullptr) return successor(node->right);
        if (node->left == nullptr && node->right == nullptr) return nullptr;
        return node->left != nullptr ? node->left : node->right;
    }

    Node* successor(Node* node) {
        Node* temp = node;
        while (temp->left != nullptr) temp = temp->left;
        return temp;
    }

    void fixViolation(Node* node) {
        Node* parent = nullptr;
        Node* grandParent = nullptr;

        while (node != root && node->color == RED && node->parent->color == RED) {
            parent = node->parent;
            grandParent = parent->parent;

            if (parent == grandParent->left) {
                Node* uncle = grandParent->right;

                if (uncle != nullptr && uncle->color == RED) {
                    grandParent->color = RED;
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    node = grandParent;
                } else {
                    if (node == parent->right) {
                        rotateLeft(parent);
                        node = parent;
                        parent = node->parent;
                    }
                    rotateRight(grandParent);
                    std::swap(parent->color, grandParent->color);
                    node = parent;
                }
            } else {
                Node* uncle = grandParent->left;

                if (uncle != nullptr && uncle->color == RED) {
                    grandParent->color = RED;
                    parent->color = BLACK;
                    uncle->color = BLACK;
                    node = grandParent;
                } else {
                    if (node == parent->left) {
                        rotateRight(parent);
                        node = parent;
                        parent = node->parent;
                    }
                    rotateLeft(grandParent);
                    std::swap(parent->color, grandParent->color);
                    node = parent;
                }
            }
        }
        root->color = BLACK;
    }

    void fixDoubleBlack(Node* node) {
        if (node == root) return;

        Node* sibling = node->sibling();
        Node* parent = node->parent;
        if (sibling == nullptr) {
            fixDoubleBlack(parent);
        } else {
            if (sibling->color == RED) {
                parent->color = RED;
                sibling->color = BLACK;
                if (sibling == parent->left) {
                    rotateRight(parent);
                } else {
                    rotateLeft(parent);
                }
                fixDoubleBlack(node);
            } else {
                if (sibling->hasRedChild()) {
                    if (sibling->left != nullptr && sibling->left->color == RED) {
                        if (sibling == parent->left) {
                            sibling->left->color = sibling->color;
                            sibling->color = parent->color;
                            rotateRight(parent);
                        } else {
                            sibling->left->color = parent->color;
                            rotateRight(sibling);
                            rotateLeft(parent);
                        }
                    } else {
                        if (sibling == parent->left) {
                            sibling->right->color = parent->color;
                            rotateLeft(sibling);
                            rotateRight(parent);
                        } else {
                            sibling->right->color = sibling->color;
                            sibling->color = parent->color;
                            rotateLeft(parent);
                        }
                    }
                    parent->color = BLACK;
                } else {
                    sibling->color = RED;
                    if (parent->color == BLACK) {
                        fixDoubleBlack(parent);
                    } else {
                        parent->color = BLACK;
                    }
                }
            }
        }
    }

    void rotateLeft(Node* node) {
        Node* rightNode = node->right;
        node->right = rightNode->left;

        if (node->right != nullptr) node->right->parent = node;
        rightNode->parent = node->parent;

        if (node->parent == nullptr) root = rightNode;
        else if (node == node->parent->left) node->parent->left = rightNode;
        else node->parent->right = rightNode;

        rightNode->left = node;
        node->parent = rightNode;
    }

    void rotateRight(Node* node) {
        Node* leftNode = node->left;
        node->left = leftNode->right;

        if (node->left != nullptr) node->left->parent = node;
        leftNode->parent = node->parent;

        if (node->parent == nullptr) root = leftNode;
        else if (node == node->parent->left) node->parent->left = leftNode;
        else node->parent->right = leftNode;

        leftNode->right = node;
        node->parent = leftNode;
    }

    void inorderHelper(Node* root) {
        if (root == nullptr) return;
        inorderHelper(root->left);
        std::cout << root->data << " ";
        inorderHelper(root->right);
    }

    void generateGraphvizHelper(std::ofstream& file, Node* root) {
        if (root->left != nullptr) {
            file << root->data << " -> " << root->left->data << ";\n";
            generateGraphvizHelper(file, root->left);
        } else {
            file << "null" << root->data << "L [shape=point];\n";
            file << root->data << " -> null" << root->data << "L;\n";
        }

        if (root->right != nullptr) {
            file << root->data << " -> " << root->right->data << ";\n";
            generateGraphvizHelper(file, root->right);
        } else {
            file << "null" << root->data << "R [shape=point];\n";
            file << root->data << " -> null" << root->data << "R;\n";
        }
    }
};

int main() {
    RedBlackTree tree;
    tree.insert(10);
    tree.insert(20);
    tree.insert(30);
    tree.insert(15);
    tree.insert(25);
    tree.insert(5);

    tree.generateGraphviz("rbtree.dot");

    std::cout << "Graphviz dot file generated as rbtree.dot" << std::endl;

    return 0;
}
// Output
digraph G {
10 -> 5;
10 -> 20;
20 -> 15;
20 -> 30;
30 -> 25;
null5L [shape=point];
5 -> null5L;
null5R [shape=point];
5 -> null5R;
null15L [shape=point];
15 -> null15L;
null15R [shape=point];
15 -> null15R;
null25L [shape=point];
25 -> null25L;
null25R [shape=point];
25 -> null25R;
null30L [shape=point];
30 -> null30L;
null30R [shape=point];
30 -> null30R;
}

  10
 /  \
5    20
    /  \
   15  30
       /
      25

总结

红黑树(Red-Black Tree)是一种自平衡二叉搜索树,常用于需要高效插入、删除和查找操作的数据结构中。红黑树的特点包括每个节点是红色或黑色、根节点是黑色、红色节点的子节点必须是黑色、从任一节点到其每个叶子节点的路径上的黑色节点数目相同。

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

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

相关文章

umijs脚手架

node 16.9.1 注意node版本的问题 node 18.20.0 这个问题其实是node与中端连接出错&#xff0c;无法初始化TTY&#xff08;终端设备&#xff09;&#xff0c;可以用cmd命令行来创建umi项目 nvm管理node https://github.com/coreybutler/nvm-windows/releases 这是nvm-window…

【CRASH】freelist异常导致的异常地址访问

freelist异常导致的异常地址访问 问题现象初步分析继续深入新的发现沙盘推演寻找元凶分析代码后记 问题现象 项目一台设备几天内出现了两次crash&#xff0c;都是异常地址访问导致。 [66005.261660] BUG: unable to handle page fault for address: ffffff8881575110初步分析…

哪个品牌台灯护眼效果好?几款护眼效果好的专业护眼灯品牌推荐

随着科技的不断发展和生活方式的改变&#xff0c;儿童青少年近视率的增长趋势引起了人们的关注。近视不仅对孩子们的视力健康构成威胁&#xff0c;还可能对他们的学习和日常生活带来不便。因此&#xff0c;如何有效地预防和改善儿童青少年的视力问题成为了一个亟待解决的课题。…

MES里面有质量模块,为什么还要实施质量管理软件(QMS)

为什么一些知名头部的大厂&#xff0c;已经有了MES , 却还都去实施了质量管理软件&#xff08;QMS&#xff09;? 答&#xff1a;是这些MES里面的质量模块不能满足客户的需求。 那么来看看&#xff0c;从质量管理的角度来看&#xff0c;QMS软件系统是什么样子的&#xff1f; …

《现代通信原理与技术》码间串扰和​​​​​​​无码间串扰的眼图对比实验报告

实 验&#xff1a;码间串扰和无码间串扰的眼图对比实验报告 摘 要&#xff1a; 在数字通信系统中&#xff0c;码间串扰&#xff08;Inter-Symbol Interference, ISI&#xff09;是影响信号质量和系统性能的重要因素之一。本实验通过MATLAB软件生成并对比了受码间串扰影响和未…

MBTI:探索你的性格类型

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

VL53L4CD TOF开发(3)----检测阈值

VL53L4CD TOF开发.3--检测阈值 概述视频教学样品申请完整代码下载实现demo硬件准备技术规格系统框图应用示意图生成STM32CUBEMX选择MCU串口配置IIC配置 XSHUTGPIO1X-CUBE-TOF1app_tof.c详细解释主程序演示结果 概述 最近在弄ST和瑞萨RA的课程&#xff0c;需要样片的可以加群申…

RabbitMQ安装配置,封装工具类,发送消息及监听

1. Get-Started docker安装rabbitmq 拉取镜像 [rootheima ~]# docker pull rabbitmq:3.8-management 3.8-management: Pulling from library/rabbitmq 7b1a6ab2e44d: Pull complete 37f453d83d8f: Pull complete e64e769bc4fd: Pull complete c288a913222f: Pull complet…

第104天: 权限提升-Linux 系统环境变量定时任务权限配置不当MDUT 自动化

目录 案例一&#xff1a;Linux-环境变量文件配合 SUID-本地 案例二&#xff1a;Linux-定时任务打包配合 SUID-本地 案例三&#xff1a;Linux-定时任务文件权限配置不当-WEB&本地 案例四&#xff1a;Linux-第三方软件 MYSQL 数据库提权-WEB&本地 隧道出网 手工提权…

解决外网404:清除DNS缓存并配置host主机使用知名公共DNS服务

在 Windows 上清除/刷新 DNS 缓存 对于所有Windows版本&#xff0c;清除DNS缓存的过程都是相同的。你需要使用管理员权限打开命令提示符并运行ipconfig /flushdns。 浏览器清除DNS缓存 大多数现代的Web浏览器都有一个内置的DNS客户端&#xff0c;以防止每次访问该网站时…

男士穿什么内裤最透气?舒适透气的男士内裤推荐

作为一名专业的测评博主&#xff0c;我深知男士内裤对于日常穿着的重要性。因此&#xff0c;我决定深入挖掘男士内裤的细节之处&#xff0c;为大家带来最真实、最客观的评测体验。通过对比不同品牌、不同材质的男士内裤&#xff0c;我希望能帮助大家找到真正适合自己的那一款。…

Plonky3和Binius中的Brakedown多项式承诺协议解析及优化(3)

3.2 Expander Graph and Linear-Time Encodable Linear Code 线性时间编码是线性纠错码的一种&#xff0c;核心是扩展图&#xff08;Expander Graph&#xff09;&#xff0c;如下图所示&#xff1a; Figure 3 Expander Graph Expander Graph是一种具有强连通性的稀疏图&#…

CV预测:快速使用DenseNet神经网络

AI预测相关目录 AI预测流程&#xff0c;包括ETL、算法策略、算法模型、模型评估、可视化等相关内容 最好有基础的python算法预测经验 EEMD策略及踩坑VMD-CNN-LSTM时序预测对双向LSTM等模型添加自注意力机制K折叠交叉验证optuna超参数优化框架多任务学习-模型融合策略Transform…

App首页,美不胜收呀,虽说app没落了,但设计思想通用呀。

一个精心设计的首页仍然能够吸引用户的注意力。一个美观而富有创意的首页可以提升用户体验&#xff0c;增加用户的留存率和活跃度。 当我们打开一个app时&#xff0c;首页是用户第一眼看到的界面&#xff0c;因此设计师需要在有限的空间内展示出app的核心功能和特点。一个好的首…

短视频五大要素:成都科成博通文化传媒公司

短视频五大要素&#xff1a;揭秘成功视频的关键 在数字媒体时代&#xff0c;短视频已成为人们生活中不可或缺的一部分。无论是社交平台的日常分享&#xff0c;还是品牌营销的重要工具&#xff0c;短视频都以其短小精悍、内容丰富的特点赢得了广泛的关注和喜爱。然而&#xff0…

《数据安全产品及服务购买决策参考》

“新全球化”下的数据安全威胁态势与挑战 随着中国企业数字化转型和数字经济的高速发展&#xff0c;数据要素和数据安全的战略价值正不断提升。 同时&#xff0c;在“脱钩”与“新全球化”的全球政治经济博弈中&#xff0c;中国作为全球重要的数据安全市场之一&#xff0c;其…

软件构造 | Equality in ADT and OOP

软件构造 | Equality in ADT and OOP &#x1f9c7;1 Three ways to regard equality 1.1 Using AF to define the equality ADT是对数据的抽象&#xff0c; 体现为一组对数据的操作 抽象函数AF&#xff1a;内部表示→抽象表示 基于抽象函数AF定义ADT的等价操作&#xff0…

如何确保远程桌面安全

在数字化快速发展的今天&#xff0c;远程桌面技术广泛应用于企业办公、技术支持以及个人使用等领域。然而&#xff0c;随之而来的安全问题也不容忽视。白名单技术作为一种重要的安全防护手段&#xff0c;在确保远程桌面安全方面发挥着至关重要的作用。 一、白名单技术概述 白名…

[Qt] Qt Creator 以及 Qt 在线安装教程

一、Qt Creator 下载及安装 1、从以下镜像源下载安装包常规安装即可 Qt Creator 也可以在第二步Qt 在线安装时一次性勾选安装&#xff0c;见后文 Qt Creator 中科大源下载地址 二、Qt 在线安装 1、根据所在平台选择对应的安装器下载 Qt 在线安装器下载 2、可能的安装报错…

[华为北向网管NCE开发教程(6)消息订阅

1.作用 之前介绍的都是我们向网管NCE发起请求获取数据&#xff0c;消息订阅则反过来&#xff0c;是网管NCE系统给我们推送信息。其原理和MQ&#xff0c;JMS这些差不多&#xff0c;这里不过多累述。 2.场景 所支持订阅的场景有如下&#xff0c;以告警通知为例&#xff0c;当我…