顺序表(二)

news2024/10/7 8:26:25

文章目录

  • 前言
  • 一.什么是链表
  • 二.线性表的链表结构
    • 2.1链表的初始
    • 2.2 链表的分类
    • 2.3 单链表
    • 2.4 双链表
  • 三.java里面的LinkedList API
    • 3.1 基础操作
    • 3.2 链表的遍历操作
  • 四.模拟实现LinkedList的相关操作
    • 创建一个链表
    • 头插法
    • 尾插法
    • 任意位置插入,第一个数据节点为0号下标
    • 查找是否包含关键字key是否在单链表当中
    • 删除第一次出现关键字为key的节点
    • 删除所有值为key的节点
    • 得到单链表的长度
    • 打印链表
    • 清空链表
  • 五.链表的相关题目
    • 1. 删除链表中等于给定值 val 的所有节点。[OJ链接](https://leetcode.cn/problems/remove-linked-list-elements/description/)
    • 2. 反转一个单链表[ OJ链接](https://leetcode.cn/problems/reverse-linked-list/description/)
    • 3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。[OJ链接](https://leetcode.cn/problems/middle-of-the-linked-list/description/)
    • 4. 输入一个链表,输出该链表中倒数第k个结点。 OJ链接.
    • 5. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。[OJ链接](https://leetcode.cn/problems/merge-two-sorted-lists/description/)
    • 6. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。[OJ链接](https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking)
    • 7. 链表的回文结构。
    • 8. 输入两个链表,找出它们的第一个公共结点[OJ链接](https://leetcode.cn/problems/intersection-of-two-linked-lists/)
    • 9. 给定一个链表,判断链表中是否有环。[OJ链接](https://leetcode.cn/problems/linked-list-cycle/description/)
    • 10.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL


前言

上节课已经说明了线性表的顺序结构,这节课我们将继续了解线性结构中链式结构,大家一定很期待吧,快来加入,跟我一起学习吧.

一.什么是链表

链表由一组节点组成,每个节点包含两部分:本节点的数据域和指向下一个节点的指针(或链)。通过这组节点和指针的关系,形成一个链表。
与数组相比,链表的优点在于插入和删除操作简单,不需要移动大量的数据;缺点是不能直接访问任意位置的节点,需要从起始节点开始顺序遍历。链表可用于实现队列和栈等数据结构。

二.线性表的链表结构

2.1链表的初始

所谓的链表就像火车的一节一节的车厢,如下图所示:
在这里插入图片描述
具体的结构就如下图所示:
在这里插入图片描述

2.2 链表的分类

单向或者双向
在这里插入图片描述
带头后者不带头
在这里插入图片描述
循环和非循环
在这里插入图片描述

2.3 单链表

这就是一个经典的链式存储结构.
如果说非要用代码表示的话,我暂时用java代码给大家表示一下,一个链表的具体结构长什么样子:

public class MySingleList {

    static class ListNode {
        public int val;//存储的数据
        public ListNode next;//存储下一个节点的地址

        public ListNode(int val) {
            this.val = val;
        }
    }

    public ListNode head;// 代表当前链表的头节点的引用
    }

在这里插入图片描述

其实我们还是懂了一点小心思的,我们使用了静态内部类,来构建一个完整的类,这样方便我们创建链表的结构.这里全都是以单链表的例子展开的.

2.4 双链表

public class MyLinkedList {
    static class ListNode {
        public int val;
        public ListNode prev;//前驱
        public ListNode next;//后继

        public ListNode(int val) {
            this.val = val;
        }
    }

    public ListNode head;
    public ListNode last;
    }

在这里插入图片描述

三.java里面的LinkedList API

3.1 基础操作

操作描述Java实现
boolean add(E e)尾插elist.add(e);
void add(int index, E element)e插入到index位置list.add(index, e);
boolean addAll(Collection<? extends E> c)尾插c中的元素list.addAll(c);
E remove(int index)删除index位置元素list.remove(index);
boolean remove(Object o)删除遇到的第一个olist.remove(o);
E get(int index)获取下标index位置元素list.get(index);
E set(int index, E element)将下标index位置元素设置为elementlist.set(index, element);
void clear()清空list.clear();
boolean contains(Object o)判断o是否在线性表中list.contains(o);
int indexOf(Object o)返回第一个o所在下标list.indexOf(o);
int lastIndexOf(Object o)返回最后一个o的下标list.lastIndexOf(o);
List<E> subList(int fromIndex, int toIndex)截取部分list list.subList(fromIndex, toIndex);
    public static void main(String[] args) {

        LinkedList<Integer> list = new LinkedList<>();
        list.add(1); // add(elem): 表示尾插
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        System.out.println(list.size());
        System.out.println(list);
// 在起始位置插入0
        list.add(0, 0); // add(index, elem): 在index位置插入元素elem
        System.out.println(list);
        list.remove(); // remove(): 删除第一个元素,内部调用的是removeFirst()
        list.removeFirst(); // removeFirst(): 删除第一个元素
        list.removeLast(); // removeLast(): 删除最后元素
        list.remove(1); // remove(index): 删除index位置的元素
        System.out.println(list);
// contains(elem): 检测elem元素是否存在,如果存在返回true,否则返回false
        if (!list.contains(1)) {
            list.add(0, 1);
        }

        list.add(1);
        System.out.println(list);
        System.out.println(list.indexOf(1)); // indexOf(elem): 从前往后找到第一个elem的位置
        System.out.println(list.lastIndexOf(1)); // lastIndexOf(elem): 从后往前找第一个1的位置
        int elem = list.get(0); // get(index): 获取指定位置元素
        list.set(0, 100); // set(index, elem): 将index位置的元素设置为elem
        System.out.println(list);
// subList(from, to): 用list中[from, to)之间的元素构造一个新的LinkedList返回
        List<Integer> copy = list.subList(0, 3);
        System.out.println(list);
        System.out.println(copy);
        list.clear(); // 将list中元素清空
        System.out.println(list.size());
    }

3.2 链表的遍历操作

分为俩种
foreach遍历
迭代器遍历

    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        list.add(1); // add(elem): 表示尾插
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        System.out.println(list.size());
// foreach遍历
        for (int e : list) {
            System.out.print(e + " ");
        }
        System.out.println();
// 使用迭代器遍历---正向遍历
        ListIterator<Integer> it = list.listIterator();
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
        System.out.println();
// 使用反向迭代器---反向遍历
        ListIterator<Integer> rit = list.listIterator(list.size());
        while (rit.hasPrevious()) {
            System.out.print(rit.previous() + " ");
        }
        System.out.println();
    }

四.模拟实现LinkedList的相关操作

我们使用过LinkedList之后,大家一定很好奇它是怎么实现的吧,接下来我们来看看它究竟是怎么一回事.
注意:我们这里全都是以单链表的实现为例子的,

创建一个链表

创建一个链表,我们是以单链表为例子的.

public class MySingleList {

    static class ListNode {
        public int val;//存储的数据
        public ListNode next;//存储下一个节点的地址

        public ListNode(int val) {
            this.val = val;
        }
    }

    public ListNode head;// 代表当前链表的头节点的引用
    }
   

创建链表的方法,我们选择手动创建

  public void createLink() {
        ListNode listNode1 = new ListNode(12);
        ListNode listNode2 = new ListNode(45);
        ListNode listNode3 = new ListNode(23);
        ListNode listNode4 = new ListNode(90);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4; /* */
        head = listNode1;
    }

头插法

头插法的意思顾名思义就是只能从头部插入.

具体的过程就是如下图所示:
在这里插入图片描述
代码展示:

  public void addFirst(int data){
        ListNode listNode = new ListNode(data);
        listNode.next = head;
        head = listNode;
    }

尾插法

尾插法是分为俩种情况的,第一种是没有节点,我们直接可以让头结点指向即可.第二种是有节点了,我们需要定义一个节点,让它执行到最后一个节点,让最后一个节点指向新节点.

在这里插入图片描述
代码如下:

    //尾插法 O(N)    找尾巴的过程
    public void addLast(int data){
        ListNode listNode = new ListNode(data);
        if(head == null) {
            head = listNode;
            return;
        }
        ListNode cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = listNode;
    }

任意位置插入,第一个数据节点为0号下标

这里其实是有讲究的,我们需要找到插入的前一个节点,在进行插入操作.
这里就有俩个步骤了.
1.找到前一个节点
2.进行插入.
具体图示如下:

在这里插入图片描述

//任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data)
            throws ListIndexOutOfException{
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = findIndexSubOne(index);
        ListNode listNode = new ListNode(data);
        listNode.next = cur.next;
        cur.next = listNode;
    }
    private ListNode findIndexSubOne(int index) {
        ListNode cur = head;
        int count = 0;
        while (count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }
        private void checkIndex(int index) throws ListIndexOutOfException{
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("index位置不合法");
        }
    }

查找是否包含关键字key是否在单链表当中

在这里插入图片描述

  public boolean contains(int key){
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

删除第一次出现关键字为key的节点

删除第一次出现关键词为key的节点,实际上是分为俩个步骤的.
1.查找到要删除的数的前一个节点
2.根据前一个节点找到删除的数
3.删除这个数.
图示如下:
在这里插入图片描述
代码如下:

public void remove(int key){
        if(head == null) {
            return ;//一个节点都没有
        }
        if(head.val == key) {
            head = head.next;
            return;
        }
        ListNode cur = searchPrev(key);
        if(cur == null) {
            return;
        }
        ListNode del = cur.next;//要删除的节点
        cur.next = del.next;
    }
     private ListNode findIndexSubOne(int index) {
        ListNode cur = head;
        int count = 0;
        while (count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }

删除所有值为key的节点

这个删除所有节点的操作,其实就是想发设发遍历整个链表然后进行删除操作.
1.查找到要删除的数的前一个节点
2.根据前一个节点找到删除的数
3.删除这个数.
4.循环这个操作,直到遍历完整个链表
在这里插入图片描述
代码如下:

 public void removeAllKey(int key){
        if(head == null) {
            return;
        }
        /*while(head.val == key) {
            head = head.next;
        }*/
        ListNode prev = head;
        ListNode cur = head.next;
        while (cur != null) {
            if(cur.val == key) {
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        if(head.val == key) {
            head = head.next;
        }
    }

得到单链表的长度

这个就是遍历链表的操作,得到最终的长度,我这里就直接给出代码了

 //得到单链表的长度 O(N)
    public int size(){
        int count = 0;
        ListNode cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

打印链表

遍历链表依次进行打印即可.

 public void display() {
        //如果说 把整个链表 遍历完成 那么 就需要 head == null
        // 如果说 你遍历到链表的尾巴  head.next == null
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

清空链表

因为有头结点,我把头结点置为空即可.

    public void clear() {
        head = null;

    }

五.链表的相关题目

1. 删除链表中等于给定值 val 的所有节点。OJ链接

这里就不做过多赘述了,这跟我们前面删除定值的val是一样的操作.

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //删除值相同的头结点后,可能新的头结点也值相等,用循环解决
        while(head!=null&&head.val==val){
            head=head.next;
        }
        if(head==null)
            return head;
        ListNode prev=head;
        //确保当前结点后还有结点
        while(prev.next!=null){
            if(prev.next.val==val){
                prev.next=prev.next.next;
            }else{
                prev=prev.next;
            }
        }
        return head;
    }
}

2. 反转一个单链表 OJ链接

这道题十分有意思,我们给出的思路是用头插法进行链表的翻转,具体的图示如下:

在这里插入图片描述

具体代码:

 public ListNode reverseList() {
        if(head == null) {
            return null;
        }
        //说明 只有一个节点
        if(head.next == null) {
            return head;
        }
        ListNode cur = head.next;
        head.next = null;

        while (cur != null) {
            ListNode curNext = cur.next;
            //头插法 插入cur
            cur.next = head;
            head = cur;
            cur = curNext;
        }
        return head;
    }

3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。OJ链接

首先简单的说一下这道题的思路,我们要返回中间节点,这个链表其实是有俩种情况的,第一种就是链表为偶数的时候,另外一种就是链表为奇数的时候.
我这里用图示给大家演示一下:
在这里插入图片描述
另外我们怎么解决这个问题找中间节点的问题呢?我们引入了快慢指针的概念.大家只要记住,快慢指针是一种算法技巧,使用两个指针遍历链表或数组,一个快指针和一个慢指针。它们以不同的速度移动,快指针每次移动两个节点,慢指针每次移动一个节点。通过这两个指针,可以实现对链表的多种操作。
下面我们就来解决这个问题:

在这里插入图片描述
以上就是我门先让fast先走两步,然后再让slow走一步,走到fast为null或者fast.next为null的时候结束.这样奇数个和偶数个都找到了中间节点.
代码如下:

    public ListNode middleNode() {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

4. 输入一个链表,输出该链表中倒数第k个结点。 OJ链接.

OJ链接
这个问题我们还是能用快慢指针解决,你们看我接下来的操作就知道了
1.先让fast走k-1步
2. fast走完之后和slow开始一步一步走
3.当fast.next为空的时候,slow所指的位置就是倒数第K个
具体操作如下图所示:
在这里插入图片描述

代码如下:

 public ListNode findKthToTail(int k) {
        if(k <= 0 || head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        //1. fast走k-1步
        while (k-1 != 0) {
            fast = fast.next;
            if(fast == null) {
                return null;
            }
            k--;
        }
        //2、3、
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

5. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。OJ链接

这道题究竟要我们干什么呢?大家可以看看下面的图片
在这里插入图片描述

我们看到问题就是合并两个有序链表,关键是构建一个新的有序链表,这里的难点是如何同时遍历两个链表。
我给出以下的思路:

  1. 定义两个指针list1、list2分别指向两个链表的头节点head1和head2。
  2. 比较list1和list2指向的节点值,将值较小的节点接到结果链表上,并将相应的指针往后移一节点。
  3. 重复步骤2,直到list1t或者list2到达链表尾部。
  4. 将未到达尾部的链表直接接到结果链表尾部。
  5. 返回结果链表的头节点。

具体的图解如下:
在这里插入图片描述
重复这个步骤即可.

具体的代码操作如下:

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
          ListNode newHead=new ListNode (0);
       ListNode tmp=newHead;
       while(list1 != null && list2 !=null){
            if(list1.val <list2.val){
                tmp.next=list1;
                list1=list1.next;
                tmp=tmp.next;
            }else{
                tmp.next=list2;
                list2=list2.next;
                tmp=tmp.next;
            }
       }
       //循环走完以后,会出现俩种情况
       if(list1 != null){
            tmp.next=list1;
       }
       if(list2 !=null){
            tmp.next=list2;
       }
       return newHead.next;
    }

6. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。OJ链接

具体思路:

  1. 定义两个链表bs和as,用于存放值小于x和大于等于x的节点。初始时bs和as都指向null。
  2. 遍历原链表,当节点值小于x时,将该节点添加到bs链表尾部。当节点值大于等于x时,将该节点添加到as链表尾部。
  3. 遍历结束后,bs链表代表值小于x的节点,as链表代表值大于等于x的节点。
  4. 判断bs链表和as链表是否同时不为空。如果bs链表为空,直接返回as链表头部。如果as链表为空,直接返回bs链表头部。
  5. 如果bs链表和as链表同时不为空,则将bs链表尾部节点的next指针指向as链表头部。
  6. 如果as链表不为空,则将as链表尾部节点的next指针指向null。
  7. 返回bs链表头部作为结果。

在这里插入图片描述

具体代码:

public ListNode partition( int x) {
        // write code here
        ListNode bs = null;
        ListNode be = null;
        ListNode as = null;
        ListNode ae = null;

        ListNode cur = head;
        while (cur != null) {
            if(cur.val < x) {
                if(bs == null) {
                    bs = cur;
                    be = cur;
                }else {
                    be.next = cur;
                    be = be.next;
                }
            }else {
                if(as == null) {
                    as = cur;
                    ae = cur;
                }else {
                    ae.next = cur;
                    ae = ae.next;
                }
            }
            cur = cur.next;
        }
        // 有可能不会同时存在小于x 和 大于等于x 的数据
        if(bs == null) {
            return as;
        }
        //第一段不为空
        be.next = as;
        //第2个段为空不为空的问题
        if(as != null) {
            ae.next = null;
        }
        return bs;
    }


7. 链表的回文结构。

判断链表的回文结构,这个题目的思路也很明确,比如我们判断数字的回文结构是怎么判断的,现在只是换到了链表而已.OJ链接
思路如下:

  1. 找到链表的中点,可以使用快慢指针。快指针移动两步,慢指针移动一步,当快指针移动到链表尾部时,慢指针正好在中点。
  2. 反转链表的后半部分。可以从慢指针开始,注意记录前一个节点和后一个节点。
  3. 比较链表前半部分和后半部分的值。前半部分从头节点开始,后半部分从慢指针开始。
  4. 如果全部比较相等,则链表为回文结构。否则不是。
  5. 恢复链表的结构,需要反转后半部分链表。
    在这里插入图片描述

代码如下:

public boolean chkPalindrome() {
        if(head == null) {
            return false;
        }
        if(head.next == null) {
            return true;
        }
        ListNode fast = head;
        ListNode slow = head;
        //1、找中间节点
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        //2、 翻转
        ListNode cur = slow.next;//代表当前需要翻转的节点
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curNext;
        }
        //3、一个从头往后  一个从后往前
        while (slow != head) {
            if(head.val != slow.val) {
                return false;
            }
            //偶数的情况
            if(head.next == slow) {
                return true;
            }
            slow = slow.next;
            head = head.next;

        }
        return true;
    }

8. 输入两个链表,找出它们的第一个公共结点OJ链接

这里实际的情况就是如下图所示:

在这里插入图片描述
找俩个单链表节点的相交值
1.我们可以定义俩个指针,来指向俩个链表,
2.比较俩个链表的大小
3.让长链表先走k步.
4,然后再一起走,如果相遇,就是相交链表

在这里插入图片描述

具体代码:

  public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        /*
        找俩个单链表节点的相交值
        我们可以定义俩个指针,来指向俩个链表,
        让长链表先走,然后再一起走。
        问题来了,我们就能知道相遇点了
        */
        //首先我们去解决,哪一个更长的问题
        int lenA=0;
        int lenB=0;
        ListNode pl=headA;
        ListNode ps=headB;
        while(pl !=null){
            lenA++;
            pl=pl.next;
        }
         while(ps !=null){
            lenB++;
            ps=ps.next;
        }
        pl=headA;
        ps=headB;
        int len =lenA-lenB;
        if(len <0  ){
            pl=headB;
            ps=headA;
            len=lenB -lenA;
        }
        //然后就知道,那个长,那个短了
        while(len !=0){
            pl=pl.next;
            len--;
        }
        while(pl != ps){
            pl=pl.next;
            ps=ps.next;
        }
        if (pl==ps && pl==null){
            return null;
        }
        return pl;

        
        
    }
}

9. 给定一个链表,判断链表中是否有环。OJ链接

在这里插入图片描述
具体思路:

  1. 使用快慢指针,快指针每次走两步,慢指针每次走一步。
  2. 如果快指针最终走到了链表尾部,说明链表无环,返回false。
  3. 否则快慢指针最终会相遇在环内,返回true。
    为什么我们会使用快慢指针呢?是因为实质上就是我们小学时候使用的追击问题解题思路.我下面将展示一下我的思路.
    在这里插入图片描述

具体代码

 public boolean hasCycle() {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                return true;
            }
        }
        return false;
    }

10.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL

OJ链接
让一个指针从链表起始位置开始遍历链表,同时让一个指针从判环时相遇点的位置开始绕环运行,两个指针都是每次均走一步,最终肯定会在入口点的位置相遇。

具体思路:

  1. 先判断链表是否有环,使用快慢指针可以判断。如果无环,直接返回null。
  2. 如果有环,则将快慢指针重新置于链表头部。慢指针移动一步,快指针移动两步。
  3. 快慢指针会再次相遇,相遇点就是环入口,返回该节点。

为什么快慢指针能找到环入口?

因为从链表头部到环入口的距离等于相遇点到环入口的距离。快指针速度是慢指针的两倍,所以快指针走的距离是慢指针距离的两倍。
当快慢指针在环内相遇后,快指针已经比慢指针多走了一圈环的距离。所以如果从头节点和相遇点各走相同的距离,最终会在环入口相遇。
我来具体的解释一下我的具体思路:
具体思路:
在这里插入图片描述

具体代码:

public ListNode detectCycle() {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                break;
            }
        }
        if(fast == null || fast.next == null) {
            return null;
        }
        //
        slow = head;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }

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

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

相关文章

【网络安全】记一次杀猪盘渗透实战

看起来非常假的网站&#xff0c;这个网站是没有 cdn 的用的是 thinkphpk 框架搭建的。 先打一波 poc 没有效果 访问一下后台直接在 url 后面加/admin。 一个开源的 cms 还没有验证码尝试用 burp 进行爆破&#xff0c;首先在火狐上设置代理 ip 为 127.0.0.1 代理端口为 8081。 B…

性能测试----负载测试、压力测试、并发测试

性能测试&#xff1a;检测一个软件的性能。 性能测试的指标&#xff1a; 响应时间&#xff1a;用户从请求到服务器响应的时间 吞吐量&#xff1a;单位时间内成功地传送数据的数量 并发数&#xff1a;在线并且在操作的用户数 负载测试&#xff1a;加负载&#xff0c;找到让系…

内网:定位域管理员

在域渗透中&#xff0c;获取域内的一个支点后&#xff0c;需要获取管理员权限。在一个域中&#xff0c;当计算机加入域后&#xff0c;会默认给域管理员组赋予本地系统管理员权限。当计算机被添加到域中&#xff0c;成为域的成员主机时&#xff0c;系统会自动将域管理员组添加到…

( “ 图 “ 之 拓扑排序 ) 207. 课程表 ——【Leetcode每日一题】

❓207. 课程表 难度&#xff1a;中等 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课…

C#_委托简述

一.委托的分类 1.delegate关键字 直接通过delegate关键字定义委托类&#xff0c;定义示例如下&#xff1a; delegate void Calculate(int x, int y, int z); 此时可将返回值类型为void、参数类型为(int, int, int)的函数委托给Calculate&#xff0c;示例&#xff1a; Calcu…

今日立夏 — 初夏已至,万物并秀。

晴日暖风生麦气&#xff0c; 绿阴幽草胜花时。 ——《初夏即事》王安石 告别春日和煦的风&#xff0c;立夏缓缓走到眼前。 古人云&#xff1a;“四月立夏为节者&#xff0c;夏&#xff0c;大也&#xff0c;至此之时物已长大&#xff0c;故以为名。”万物生长&#xff0c;人有…

Java—JDK8新特性—Lambda表达式

目录 JDK8新特性 2.Lambda表达式 2.1 什么是Lambda表达式 2.2 为什么使用Lamdba表达式 2.3 Lambda表达式基本语法 JDK8新特性 官网提供网址&#xff1a;JDK 8 Features 2.Lambda表达式 2.1 什么是Lambda表达式 Lamdba是一个匿名函数&#xff0c;可以把Lamdba表达式理解为是…

社群人脉系统源码软件开发

社群人脉系统源码软件技术主要包括以下方面&#xff1a; 后端开发&#xff1a;使用Java、Python等编程语言&#xff0c;采用Spring、Django等框架&#xff0c;实现后台管理系统和API接口开发。 前端开发&#xff1a;使用Vue、React等前端框架&#xff0c;实现用户界面开…

ebpf-linux 安全“双刃剑”

EBPF 技术简介 eBPF全称 extended BPF&#xff0c;Linux Kernel 3.15 中引入的全新设计, 是对既有BPF架构进行了全面扩展&#xff0c;一方面&#xff0c;支持了更多领域的应用,另一方面&#xff0c;在接口的设计以及易用性上&#xff0c;也有了较大的改进。 eBPF 是一个基于寄…

PySpark基础入门(6):Spark Shuffle

PySpark基础入门&#xff08;6&#xff09;&#xff1a;Spark Shuffle - 掘金 (juejin.cn) 目录 shuffle的执行 ShuffleManager Hash Shuffle Sort Shuffle Manage Spark在DAG调度阶段会将一个Job划分为多个Stage&#xff0c;上游Stage做map工作&#xff0c;下游Stage做r…

RN系统精讲-----基础了解

原生基础 安装SDK与Tools preference > appearance > systemSetting > Android sdk 如何连接设备&#xff0c;以及开发中的常用的adb命令 USB连接设备 adb devices 查看连接设备 wifi网络连接设备 adb connect ip&#xff08;手机自己的ip地址&#xff0c;可以通过…

画图以及代码分析结合的循环队列的实现

循环队列的实现 概念以及结构实现初始化判空判满入队出队从队头获得元素从队尾获得元素释放 概念以及结构 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”…

优化| 割平面算法(2): Cover Cuts, Strengthening, Separation及其拓展(理论与实战详解)

【MIP Cutting plane method】-1: Cover cuts MIP的标准形式什么是Cover CutsCover Cuts的详细案例Stronger Cover Cuts及其案例Separation for Cover Cuts用Separation生成 Cover Cuts的详细例子调用Gurobi验证Cover Cuts和Stronger Cover Cuts的作用线性松弛模型的解加入Cove…

领域分类/识别方案

将用户输入与预定义的领域进行匹配 针对领域分类任务&#xff0c;如上图所示&#xff0c;我们首先会从不同的业务中收集大量的业务数据&#xff0c;作为基础的训练数据&#xff0c;虽然这些数据来自不同的业务&#xff0c;但是依然存在一些问题&#xff0c;主要有以下两方面&am…

YOLOv7测距+碰撞检测

YOLOv7测距碰撞检测 1. 相关配置2. 测距原理3. 标定和测距4. 碰撞检测4.1 相关代码4.2 主代码 5. 实验效果 相关链接 1. YOLOV5 单目测距&#xff08;python&#xff09; 2. YOLOV7 单目测距&#xff08;python&#xff09; 3. 具体实现效果已在Bilibili发布&#xff0c;点击…

vscode+gdbserver实现图形化调试Linux应用

一、环境&#xff1a; 1.远程Linux主机Ubuntu22.04&#xff1b; 2.vscode 1.76 二、环境搭建 1.Ubuntu 安装gdb、gdbserver、openssh-server 2.vscode 安装Remote Development、C/C 3.远程连接Linux 点击左下角的绿色按钮&#xff0c;然后选择connect to host----->…

Day1 组队竞赛、删除公共字符

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C/C相关题解 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 选择题1.C基础语法 编程题组队竞赛删除公共字符 选择题 1.C基础语法 题目&#xff1a;以下程序的运行结果是&am…

RSA加密为什么能保证安全

问题&#xff1a;我们都知道RSA加密是安全的&#xff0c;但是我们在使用的使用&#xff0c;怎么使用才能保证数据的安全传输呢&#xff1f; 一、原则&#xff1a;公钥机密、私钥解密、私钥签名、公钥验签 公钥私钥都可以加密和解密数据&#xff0c;但是因为持有公钥和私钥的人…

【Elsevier】中科院2区TOP, 高被引119篇, 稳定检索22年, 1周可见刊,5月15截稿~

一、【期刊简介】 中科院2区软计算类SCI (TOP) 【期刊概况】IF:8.0-9.0, JCR1区, 中科院2区&#xff1b; 【终审周期】走期刊部系统&#xff0c;3-5个月左右录用&#xff1b; 【检索情况】SCI&EI双检&#xff1b;正刊&#xff1b; 【数据库收录年份】2001年&#xff1…

【测试】概念篇

目录 &#x1f31f;一、了解软件测试 &#x1f308;1、什么是软件测试 &#x1f308;2、软件测试与开发的区别&#xff08;常考&#xff09; &#x1f308;3、一个优秀的软件测试人员应该具备的素质 &#x1f31f;二、需求与测试用例、软件错误&#xff0c;软件生…