数据结构10 -查找_树表查找

news2024/11/17 1:45:57
  1. 创建二叉搜索树

二叉搜索树

二叉搜索树是有数值的了,二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

  • 它的左、右子树也分别为二叉排序树

下面这两棵树都是搜索树

bstree.c(二叉搜索树)


#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

//二叉树节点
struct BSTree_node
{
     unsigned int elem;
     struct BSTree_node *ltree, *rtree;  // 左右子树
};

struct BSTree_node *create_bstree(unsigned int *pt, int n);
struct BSTree_node *insert_bstree(struct BSTree_node *T, unsigned int elem);
void in_order(struct BSTree_node *tree);

int main(void)
{
       unsigned int num;
       unsigned int arr[SIZE] = {37, 22, 11, 82, 67, 9, 45, 91, 33, 52}; // 无序数组
       struct BSTree_node *mytree = NULL;
       mytree = create_bstree(arr, SIZE);  // 创建二叉树
       in_order(mytree); // 中序遍历
       printf("\n");
       return 0;
}

// 创建二叉搜索树
struct BSTree_node *create_bstree(unsigned int *pt, int n)
{
       struct BSTree_node *tree = NULL;
       for(int i = 0; i < n; i++)
       {
             tree = insert_bstree(tree, *pt);
             pt++;
       }
       return tree;
}

struct BSTree_node *insert_bstree(struct BSTree_node *T, unsigned int elem)
{
      if(!T)
      {
             T = (struct BSTree_node *)malloc(sizeof(struct BSTree_node));
             T->elem = elem;
             T->ltree = T->rtree = NULL;
      }
      else if(elem < T->elem);
      {
             T->ltree = insert_bstree(T->ltree, elem);   //递归
      }
      else if(elem > T->elem);
      {
             T->rtree = insert_bstree(T->rtree, elem);   //递归
      }
      else
      {
             printf("inserting repeat node is fobidden.\n");
             exit(0);
      }
      return T;
}
// 遍历
void in_order(struct BSTree_node *tree)
{
      if(tree)
      {
            in_order(tree->ltree);
            printf("%d", tree->elem);
            in_order(tree->rtree);
      }
}

力扣题目

98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:


节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:


输入:root = [2,1,3]
输出:true

示例 2:


输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
//递归1  ---》中序遍历 左 - 中 - 右,所以中序遍历应该是有序数组(单调递增)
class Solution {
private:
    vector<int> vec;
    void traversal(TreeNode* root) {
        if (root == NULL) return;
        traversal(root->left);    // 左
        vec.push_back(root->val); // 中 // 将二叉搜索树转换为有序数组
        traversal(root->right);   // 右
    }
public:
    bool isValidBST(TreeNode* root) {
        vec.clear(); // 不加这句在leetcode上也可以过,但最好加上
        traversal(root);
        for (int i = 1; i < vec.size(); i++) {
            // 注意要小于等于,搜索树里不能有相同元素
            if (vec[i] <= vec[i - 1]) return false;
        }
        return true;
    }
};

//递归2  中序遍历
class Solution {
public:
    TreeNode* pre = NULL; // 用来记录前一个节点
    bool isValidBST(TreeNode* root) {
        if (root == NULL) return true;      // 空二叉树属于任何是各种二叉树
        bool left = isValidBST(root->left);   // 左

        if (pre != NULL && pre->val >= root->val) return false;
        pre = root; // 记录前一个节点

        bool right = isValidBST(root->right); // 右
        return left && right;
    }
};

//迭代
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = NULL; // 记录前一个节点
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) {
                st.push(cur);
                cur = cur->left;                // 左
            } else {
                cur = st.top();                 // 中
                st.pop();
                if (pre != NULL && cur->val <= pre->val)
                return false;
                pre = cur; //保存前一个访问的结点

                cur = cur->right;               // 右
            }
        }
        return true;
    }
};
  1. 查找_添加二叉搜索树

二叉搜索树插入以及查找数值

bstree_find.c


#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

//二叉树节点
struct BSTree_node
{
     unsigned int elem;
     struct BSTree_node *ltree, *rtree;  // 左右子树
};

struct BSTree_node *create_bstree(unsigned int *pt, int n);
struct BSTree_node *insert_bstree(struct BSTree_node *T, unsigned int elem);
void in_order(struct BSTree_node *tree);

int main(void)
{
       unsigned int num;
       unsigned int arr[SIZE] = {37, 22, 11, 82, 67, 9, 45, 91, 33, 52}; // 无序数组
       struct BSTree_node *mytree = NULL;
       mytree = create_bstree(arr, SIZE);  // 创建二叉树
       in_order(mytree); // 中序遍历
       printf("\n");
       //查找
       printf("please enter a number you want to find in the BSTree:\n");
       scanf("%d", &num);
       if(search_bstree(mytree, num))
                printf("find %d in the mytree.\n", num);
       else
                printf("can't find %d in the mytree.\n", num);   
       //插入
       printf("please enter a number you want to insert in the BSTree:\n");
       scanf("%d", &num);
       mytree = insert_bstree(mytree, num);
       in_order(mytree);
       printf("\n");

       return 0;
}

// 创建二叉搜索树
struct BSTree_node *create_bstree(unsigned int *pt, int n)
{
       struct BSTree_node *tree = NULL;
       for(int i = 0; i < n; i++)
       {
             tree = insert_bstree(tree, *pt);
             pt++;
       }
       return tree;
}
// 创建二叉搜索树插入节点
struct BSTree_node *insert_bstree(struct BSTree_node *T, unsigned int elem)
{
      if(!T)
      {
             T = (struct BSTree_node *)malloc(sizeof(struct BSTree_node));
             T->elem = elem;
             T->ltree = T->rtree = NULL;
      }
      else if(elem < T->elem);
      {
             T->ltree = insert_bstree(T->ltree, elem); //递归
      }
      else if(elem > T->elem);
      {
             T->rtree = insert_bstree(T->rtree, elem); //递归
      }
      else
      {
             printf("inserting repeat node is fobidden.\n");
             exit(0);
      }
      return T;
}

//中序遍历
void in_order(struct BSTree_node *tree)
{
      if(tree)
      {
            in_order(tree->ltree);     //左
            printf("%d", tree->elem);  //中
            in_order(tree->rtree);     //右
      }
}

//二叉搜索树查找
int search_bstree(struct BSTree_node *tree, unsigned int n)
{
      struct BSTree_node *p = tree; // 指针
      while(p)
      {
            if(n == p->elem)
                  return 1;
            else if(n < p->elem)
                  p = p->ltree;
            else
                  p = p->rtree;   
      }
      return 0;
}

力扣题目

700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null

示例 1:


输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

示例 2:


输入:root = [4,2,7,1,3], val = 5
输出:[]

//c++
//递归1
class Solution {
public:                //1.返回值参数
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == NULL || root->val == val) return root; // 2.终止条件
        TreeNode* result = NULL; // 变量存放返回值
        if (root->val > val) result = searchBST(root->left, val);  // 3.单层搜索
        if (root->val < val) result = searchBST(root->right, val); // result 接住目标值指针
        return result;  // 没有搜索到result就是NULL
    }
};
//递归2
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == NULL || root->val == val) return root;
        if (root->val > val) return searchBST(root->left, val);
        if (root->val < val) return searchBST(root->right, val);
        return NULL;
    }
};

//迭代法
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        while (root != NULL) { // 当节点不为空
            if (root->val > val) root = root->left; // > 左子树遍历
            else if (root->val < val) root = root->right; // < 右子树遍历
            else return root; // 等于时返回该节点
        }
        return NULL; // 如果搜索不到
    }
};

701. 二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果

示例 1:


输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:

示例 2:


输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]

示例 3:


输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]

//递归
class Solution {
private:
    TreeNode* parent;
    void traversal(TreeNode* cur, int val) { 
        if (cur == NULL) {  //2.终止条件,找到插入位置(叶子节点)
            TreeNode* node = new TreeNode(val);
            if (val > parent->val) parent->right = node;
            else parent->left = node;
            return;
        }
        parent = cur;
        if (cur->val > val) traversal(cur->left, val);
        if (cur->val < val) traversal(cur->right, val);
        return;
    }

public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {1.确定递归参数,返回值
        parent = new TreeNode(0);
        if (root == NULL) {
            root = new TreeNode(val);
        }
        traversal(root, val);
        return root;
    }
};

//迭代
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == NULL) {
            TreeNode* node = new TreeNode(val);
            return node;
        }
        TreeNode* cur = root;
        TreeNode* parent = root; // 这个很重要,需要记录上一个节点,否则无法赋值新节点
        while (cur != NULL) {
            parent = cur;
            if (cur->val > val) cur = cur->left;
            else cur = cur->right;
        }
        TreeNode* node = new TreeNode(val);
        if (val < parent->val) parent->left = node;// 此时是用parent节点的进行赋值
        else parent->right = node;
        return root;
    }
};
  1. 删除二叉搜索树


#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

//二叉树节点
struct BSTree_node
{
     unsigned int elem;
     struct BSTree_node *ltree, *rtree;  // 左右子树
};

struct BSTree_node *create_bstree(unsigned int *pt, int n);
struct BSTree_node *insert_bstree(struct BSTree_node *T, unsigned int elem);
void in_order(struct BSTree_node *tree);
int search_bstree(struct BSTree_node *tree, unsigned int n);
struct BSTree_node *delete_bstree(struct BSTree_node *T, unsigned int elem);


int main(void)
{
       unsigned int num;
       unsigned int arr[SIZE] = {37, 22, 11, 82, 67, 9, 45, 91, 33, 52}; // 无序数组
       struct BSTree_node *mytree = NULL;
       mytree = create_bstree(arr, SIZE);  // 创建二叉树
       in_order(mytree); // 中序遍历
       printf("\n");
//查找
       printf("please enter a number you want to find in the BSTree:\n");
       scanf("%d", &num);
       if(search_bstree(mytree, num))
                printf("find %d in the mytree.\n", num);
       else
                printf("can't find %d in the mytree.\n", num);   
//插入
       printf("please enter a number you want to insert in the BSTree:\n");
       scanf("%d", &num);
       mytree = insert_bstree(mytree, num);
       in_order(mytree);
       printf("\n");

//删除
       printf("please enter a number you want to delet from the BSTree:\n");
       scanf("%d", &num);
       mytree = delete_bstree(mytree, num);
       in_order(mytree);
       printf("\n");
       
       return 0;
}

// 创建二叉搜索树
struct BSTree_node *create_bstree(unsigned int *pt, int n)
{
       struct BSTree_node *tree = NULL;
       for(int i = 0; i < n; i++)
       {
             tree = insert_bstree(tree, *pt);
             pt++;
       }
       return tree;
}
// 创建二叉搜索树插入节点
struct BSTree_node *insert_bstree(struct BSTree_node *T, unsigned int elem)
{
      if(!T)
      {
             T = (struct BSTree_node *)malloc(sizeof(struct BSTree_node));
             T->elem = elem;
             T->ltree = T->rtree = NULL;
      }
      else if(elem < T->elem);
      {
             T->ltree = insert_bstree(T->ltree, elem); //递归
      }
      else if(elem > T->elem);
      {
             T->rtree = insert_bstree(T->rtree, elem); //递归
      }
      else
      {
             printf("inserting repeat node is fobidden.\n");
             exit(0);
      }
      return T;
}

//中序遍历
void in_order(struct BSTree_node *tree)
{
      if(tree)
      {
            in_order(tree->ltree);     //左
            printf("%d", tree->elem);  //中
            in_order(tree->rtree);     //右
      }
}

//二叉搜索树查找
int search_bstree(struct BSTree_node *tree, unsigned int n)
{
      struct BSTree_node *p = tree; // 指针
      while(p)
      {
            if(n == p->elem)
                  return 1;
            else if(n < p->elem)
                  p = p->ltree;
            else
                  p = p->rtree;   
      }
      return 0;
}

//删除 使用后继点代替删除节点
struct BSTree_node *delete_bstree(struct BSTree_node *T, unsigned int elem)
{  //递归
       //1.空
       if(T == NULL)
       {
           printf("no exist %d node.\n", elem);
           exit(0);
       }
       //2.等于时
       if(T->elem == elem)
       {     //2.1 没有右子树,直接删除该节点,T指向左子树
             if(T->rtree == NULL)
             {
                  struct BSTree_node *temp = T; 
                  T = T->ltree;
                  free(temp);
             }
             else //2.2 有右子树,找右子树最左点
             {
                  struct BSTree_node *temp = T->rtree; 
                  while(temp->ltree)  //找最左点
                        temp = temp->ltree; 
                  T->elem = temp->elem;
                  T->rtree = delete_bstree(T->rtree, T->elem); // 递归删除最左节点
             }

       }
       //3.大于或者小于时
       else if(T->elem > elem)
            T->ltree = delete_bstree(T->ltree, elem);
       else
            T->rtree = delete_bstree(T->rtree, elem);
       
       return T;
}

力扣题目

450. 删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:


首先找到需要删除的节点;
如果找到了,删除它。

示例 1:


输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:


输入: root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7]
解释: 二叉树不包含值为 0 的节点

示例 3:


输入: root = [], key = 0
输出: []

确定单层递归的逻辑

这里就把二叉搜索树中删除节点遇到的情况都搞清楚。

有以下五种情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了

  • 找到删除的节点

  • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点

  • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点

  • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点

  • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。


//递归
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == nullptr) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了
        if (root->val == key) {
            // 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
            if (root->left == nullptr && root->right == nullptr) {
                ///! 内存释放
                delete root;
                return nullptr;
            }
            // 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
            else if (root->left == nullptr) {
                auto retNode = root->right;
                ///! 内存释放
                delete root;
                return retNode;
            }
            // 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
            else if (root->right == nullptr) {
                auto retNode = root->left;
                ///! 内存释放
                delete root;
                return retNode;
            }
            // 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
            // 并返回删除节点右孩子为新的根节点。
            else {
                TreeNode* cur = root->right; // 找右子树最左面的节点
                while(cur->left != nullptr) {
                    cur = cur->left;
                }
                cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置
                TreeNode* tmp = root;   // 把root节点保存一下,下面来删除
                root = root->right;     // 返回旧root的右孩子作为新root
                delete tmp;             // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)
                return root;
            }
        }
        if (root->val > key) root->left = deleteNode(root->left, key);
        if (root->val < key) root->right = deleteNode(root->right, key);
        return root;
    }
};

//迭代
class Solution {
private:
    // 将目标节点(删除节点)的左子树放到 目标节点的右子树的最左面节点的左孩子位置上
    // 并返回目标节点右孩子为新的根节点
    // 是动画里模拟的过程
    TreeNode* deleteOneNode(TreeNode* target) {
        if (target == nullptr) return target;
        if (target->right == nullptr) return target->left;
        TreeNode* cur = target->right;
        while (cur->left) {
            cur = cur->left;
        }
        cur->left = target->left;
        return target->right;
    }
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == nullptr) return root;
        TreeNode* cur = root;
        TreeNode* pre = nullptr; // 记录cur的父节点,用来删除cur
        while (cur) {
            if (cur->val == key) break;
            pre = cur;
            if (cur->val > key) cur = cur->left;
            else cur = cur->right;
        }
        if (pre == nullptr) { // 如果搜索树只有头结点
            return deleteOneNode(cur);
        }
        // pre 要知道是删左孩子还是右孩子
        if (pre->left && pre->left->val == key) {
            pre->left = deleteOneNode(cur);
        }
        if (pre->right && pre->right->val == key) {
            pre->right = deleteOneNode(cur);
        }
        return root;
    }
};

530. 二叉搜索树的最小绝对差

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值

差值是一个正数,其数值等于两值之差的绝对值。

示例 1:


输入:root = [4,2,6,1,3]
输出:1

示例 2:


输入:root = [1,0,48,null,null,12,49]
输出:1

501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:


结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树

示例 1:


输入:root = [1,null,2,2]
输出:[2]

示例 2:


输入:root = [0]
输出:[0]

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1:


输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:


输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:


输入:root = [1,2], p = 1, q = 2
输出:1


235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:


输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:


输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点1 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

47.Linux学习day01 基础命令详解1(很全面)

目录 一、Linux和Windows的区别 二、Linux系统目录结构 常见目录说明 三、Linux常见的基础命令 1.pwd 2.cd 3.ls 4.man 5. touch 6.mkdir 7. rmdir 今天正式学习了linux的一些基础操作和基础知识&#xff0c;以及linux和windows的区别。 一、Linux和Windows的区…

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接 背景目标依赖配置文件如下项目结构如下相关配置如下启动代码如下Controller如下启动成功接口调用成功 背景 工作做了一段时间&#xff0c;回忆起之前有个公司有线下笔试&#xff0c;要求考生做一个什么功能&#x…

建设全球研发中心城市,长沙与人才何以双向奔赴?

跨越山涧峡谷&#xff0c;需要搭建钢铁桥梁&#xff0c;跨越文化沟通&#xff0c;需要搭建互相理解的桥梁&#xff0c;那么&#xff0c;一座城市与人才之间的联系&#xff0c;应该搭建怎样的桥梁&#xff1f; 近日&#xff0c;长沙出台了重磅文件《中共长沙市委长沙市人民政府…

XSS漏洞原理及利用跨站请求伪造CSRF

XSS漏洞原理及利用&跨站请求伪造CSRF XSS一、案例二、什么是XSS三、XSS危害四、XSS的分类4.1、反射型XSS4.1.1、介绍4.1.2、利用过程 4.2、存储型XSS4.2.1、介绍4.2.2、利用过程4.2.3、案例 4.3、DOM型XSS4.3.1、介绍4.3.2、常用的DOM方法4.3.3、案例4.3.3.1、代码分析4.3.…

Spring源码之XML文件中Bean标签的解析1

读取XML文件&#xff0c;创建对象 xml文件里包含Bean的信息&#xff0c;为了避免多次IO&#xff0c;需要一次性读取xml文件中所有bean信息&#xff0c;加入到Spring工厂。 读取配置文件 new ClassPathResource("applicationContext.xml")ClassPathResource是Sprin…

vue动态生成行

vue代码 <el-table :data"form.lineInfos" :bordertrue style"width: 99.99%;"> <el-table-column type"index" label"序号" width"50"></el-table-column> <el-table-column prop"unitPrice&qu…

【Linux 网络】 传输层协议之TCP协议 TCP的三次握手和四次挥手

TCP协议 TCP协议段格式谈谈什么是 “可靠” 和 “不可靠”TCP协议段——序号与确认序号TCP协议段——窗口大小TCP协议段 —— 六个标志位确认应答机制&#xff08;ACK&#xff09;超时重传机制连接管理机制TCP 的三次握手四次挥手TCP三次握手四次挥手总结图 滑动窗口流量控制拥…

18. SpringBoot 如何在 POM 中引入本地 JAR 包

❤️ 个人主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;成功解决 BUG 合集 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; Spring Boot 是一种基于 Spring 框架的轻量级应用程序开发框架&#xff0c;它提供了快速开发应用程…

第126天:内网安全-隧道技术SSHDNSICMPSMB上线通讯LinuxMac

知识点 #知识点&#xff1a; 1、入站规则不出网上线方案 2、出站规则不出网上线方案 3、隧道技术-SMB&ICMP&DNS&SSH 4、控制上线-Linux&Mac&IOS&Android-连接方向&#xff1a;正向&反向&#xff08;基础课程有讲过&#xff09; -内网穿透&#xf…

vue2-vue项目中你是如何解决跨域的?

1、跨域是什么&#xff1f; 跨域本质是浏览器基于同源策略的一种安全手段。 同源策略&#xff08;sameoriginpolicy&#xff09;&#xff0c;是一种约定&#xff0c;它是浏览器最核心也是最基本的安全功能。 所谓同源&#xff08;即指在同一个域&#xff09;具有以下三个相同点…

Java对象的前世今生

文章目录 一、创建对象的步骤二、类加载机制三、内存分配指针碰撞 (内存连续)空闲列表 (内存不连续) 四、创建对象的5种方法五、浅拷贝与深拷贝 以下一行代码内部发生了什么&#xff1f; Person person new Person();一、创建对象的步骤 根据JLS中的规定&#xff0c;Java对象…

牢记这16个SpringBoot 扩展接口,写出更加漂亮的代码

1、背景 Spring的核心思想就是容器&#xff0c;当容器refresh的时候&#xff0c;外部看上去风平浪静&#xff0c;其实内部则是一片惊涛骇浪&#xff0c;汪洋一片。Springboot更是封装了Spring&#xff0c;遵循约定大于配置&#xff0c;加上自动装配的机制。很多时候我们只要引…

Scala编程语言入门教程

Scala教程 方便个人学习和查阅 学习目标 Scala介绍 简介 Scala创始人Martin Odersky马丁奥德斯基 再回到我们的scala语言&#xff0c;在Scala官网https://www.scala-lang.org/介绍了其六大特征。 Java和scala可以混编 类型推测(自动推测类型) 并发和分布式&#xff08;Ac…

nginx的优化和防盗链 重要!!!

实验一、隐藏版本号 要把nginx的版本号隐藏起来&#xff0c;防止恶意攻击 方法一&#xff1a;修改配置文件 在http模块中加入一个命令 server_token off&#xff1b; 过程&#xff1a; 备份&#xff0c;改配置文件一定要备份 修改配置文件 在http模块中添加 server_tokens …

城市与AI,正待济沧海

厦门&#xff0c;自古以来是海上丝绸之路的战略支点&#xff0c;是中国海洋贸易网络中的明珠。外来的理念与技术自厦门而入&#xff0c;中国的文化与商品自厦门而出。新事物、新科技往往在这里焕发最耀眼的生机——比如说&#xff0c;人工智能。 多年来&#xff0c;厦门持续推进…

外部排序算法总结

一.内排总结 在之前博客里&#xff0c;博主已经介绍了各种内部排序算法的原理和C语言代码实现&#xff0c;不懂的朋友可以在同系列专栏里选择查看&#xff0c;今天介绍常见排序算法的最后一点&#xff0c;也就是外部排序。在此之前&#xff0c;我们先对外部排序的各种算法做一…

Centos7/8 安装/配置 Redis5

目录 一、安装 Redis 二、创建符号链接 1.针对可执行程序设置符号链接 2.针对配置文件设置符号链接 三、修改配置文件 1.修改 ip 地址 2.关闭保护模式 四、设置工作目录 1.创建工作目录 2.在配置文件中&#xff0c;配置工作目录 五、设置日志文件 1.创建日志目录 2…

vue3中的自定义指令用法

我们都知道vue2中自定义指令全局和局部是这样写的 局部&#xff1a; 全局&#xff1a; 可vue3写法发生改变&#xff0c;如下&#xff1a; 全局&#xff1a; 局部&#xff1a;

python高阶技巧

目录 设计模式 单例模式 具体用法 工厂模式 优点 闭包 案例 修改闭包外部变量 闭包优缺点 装饰器 装饰器原理 装饰器写法 递归 递归的调用过程 递归的优缺点 用递归计算阶乘 设计模式 含义&#xff1a;设计模式是一种编程套路&#xff0c;通过这种编程套路可…

Docker极速安装Jenkins

安装 Jenkins 是一个常见的任务&#xff0c;使用 Docker 进行安装可以简化该过程并确保环境一致性。以下是在 Docker 中安装 Jenkins 的详细步骤&#xff1a; 安装 Docker: 首先&#xff0c;请确保您已在目标机器上安装了 Docker。根据您的操作系统&#xff0c;可以在 Docker 官…