我于窗中窥月光,恰如仰头见“链表”(Java篇)

本篇会加入个人的所谓‘鱼式疯言’

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言
而是理解过并总结出来通俗易懂的大白话,
小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.
🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

前言

在上一篇文章中我们讲解了线性表中:顺序表和ArrayList

而在本篇文章中小编将带着大家讲解另外一种线性表:LinkedList与链表

而在本篇文章提及的链表是: 单链表

下面让我们看看我们要学习的章节吧 💖 💖 💖

目录

  1. 链表的初识
  2. 单链表的实现
  3. 单链表的优化

一. 链表的初识

1. ArrayList 的不足

在上一篇文章中我们已经熟悉了 ArrayList 的使用,并且进行了简单的模拟实现。

通过源码知道,ArrayList底层是使用数组来存储元素

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// ...
// 默认容量是10
private static final int DEFAULT_CAPACITY = 10;
//...
// 数组:用来存储元素
transient Object[] elementData; // non-private to simplify nested class access
// 有效元素个数
private int size;
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
// ...

}

由于其底层是一段 连续空间 ,当在 ArrayList 任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为 O(n)效率比较低

因此 ArrayList不适合做任意位置插入和删除比较多的场景。因此:

java集合 中又引入了 LinkedList,即链表结构。

下面小编就介绍了我们今天的男一号选手 链表

2. 链表的概念

链表是一种 物理存储结构上非连续存储结构 ,数据元素的 逻辑顺 是通过链表中的引用 链接次序 实现的 。

在这里插入图片描述

我们平常说的 节点(又叫结点) 就是链表的基本单位,相当于上面这个火车的 每一节车厢

在这里插入图片描述

实际中链表的结构非常多样,那么链表组合起来一共有多少种结构呢 💥 💥 💥

3.链表的结构

实际中链表的结构非常多样,以下情况组合起来就有 8种链表结构

  1. 单向或者双向

在这里插入图片描述

  1. 带头或者不带头

在这里插入图片描述

  1. 循环或者非循环

在这里插入图片描述

虽然有这么多的链表的结构,但是我们重点掌握两种

第一种结构就是本篇文章要重点讲的

无头单向非循环链表(俗称 单链表 )

结构简单,一般不会单独用来存数据。 实际中更多是作为其他数据结构的子结构

在这里插入图片描述

哈希桶、图的邻接表 等等。

另外这种结构在 笔试面试 中出现很多。

第二种结构是下篇文章的重点内容哦,小伙伴们可以 期待 一下哦 💞 💞 💞

无头双向链表

在Java的集合框架库中 LinkedList底层 实现就是 无头双向循环链表

二. 单链表的实现

小伙伴们要理解链表就需要动手去 实现他们

所以这次就让小编带着小伙伴们来实现我们的 单链表 吧 💥💥💥

1. 框架搭建

<1>. 节点定义

public class MySingleLinkedList implements ISingleLinkList{


    public ListNode head;

  public static  class ListNode {

        // 存放数据
        public  int val;

        // 指向下一个节点的next
        public ListNode next;

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

    public MySingleLinkedList() {
        this.head = new ListNode(1);
    }
}

我们先定义一个

在这个类中再定义一个 内部类 ,一个个内部类就代表我们一个个 节点 ,用我们的 next 的引用来指向,另外在添加一个自身数据的 val

还需要定义个接口来 整合功能

<2>. 功能接口

package singlinklist;
public interface ISingleLinkList {


    // 打印数据
    public void display();

    // 尾删数据
    public void removeLast();

    // 头删
    public void removeFirst();

    // 指定位置删除数据
    public void remove(int pos);


    // 删除指定数据
    public void removeVal(int val);

    // 删除指定的所有数据
    public void removeValAll(int val);

    // 头插
    public void insertFirst(int val);

    // 尾插数据
    public void insertLast(int val);

    // 指定位置插入数据
    public void insert(int pos,int val);

    // 确定数据是否存在
    public boolean contains(int val);

    // 修改数据
    public void modify(int pos ,int val);

    // 清空单链表
    public void clear();


    // 链表长度
    public int length();

}

2. 功能实现

从上面的接口中我们就可以知道,咱们功能主要是四大板块: 增删查改

package singlinklist;

public class MySingleLinkedList implements ISingleLinkList{


    public ListNode head;

  public static  class ListNode {

        // 存放数据
        public  int val;

        // 指向下一个节点的next
        public ListNode next;

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

    public MySingleLinkedList() {
        this.head = new ListNode(1);
    }


    // 打印单链表
    @Override
    public void display() {

     checknull();

      ListNode cur=head;

      while (cur != null) {
          System.out.print(cur.val+" ");
          cur=cur.next;
      }

        System.out.println();


    }



    @Override
    public void insertFirst(int val) {
        checknull();

        ListNode node=new ListNode(val);

        node.next=head;
        head=node;

    }


    @Override
    public void insertLast(int val) {
        checknull();

        ListNode cur=head;

        while (cur.next !=null) {
            cur=cur.next;
        }

        ListNode node =new ListNode(val);

//       本身 cur.next=null  这行可加可不加
//        node.next=cur.next;

        cur.next=node;


    }


    // 指定位置插入
    @Override
    public void insert(int pos, int val) {

        checknull();

        if (pos==0) {
            insertFirst(val);
            return;
        }

        if (pos==length()) {
            insertLast(val);
            return;
        }

        ListNode des= indexFind(pos);
        if (des==null) {
            return;
        }

        ListNode cur=head;
        while (cur.next != des) {
            cur=cur.next;
        }

        ListNode node=new ListNode(val);

        node.next=des;
        cur.next=node;

    }



    @Override
    public void removeLast() {
      checknull();

      if (isEmpty()) {
          return;

      }

      ListNode cur=head;

      if (cur.next==null) {
          head=null;
          return;
      }

        while (cur.next.next != null) {
            cur=cur.next;
        }

        cur.next=null;

    }

    @Override
    public void removeFirst() {
        checknull();

        if (isEmpty()) {
            return;
        }

        ListNode cur=head;

        head=head.next;

        cur=null;
    }


    @Override
    public void remove(int pos) {

      checknull();

        if (isEmpty()) {
            return;
        }

        if (pos==0) {
            removeFirst();
            return;
        }

        ListNode dec=indexFind(pos);

        if (dec==null) {
            return;
        }
        ListNode cur=head;


        while (cur.next !=dec) {
            cur=cur.next;
        }

        cur.next=cur.next.next;

    }




    // 删除特定数据
    @Override
    public void removeVal(int val) {
      checknull();

      if (isEmpty()) {
          return;
      }

      ListNode cur=head;

      if (cur.val==val) {
            removeFirst();
            return;
      }


      while (cur.next != null) {

          if (cur.next.val==val) {
            cur.next=cur.next.next;
            return;
          }

          cur=cur.next;

      }


  }


    // 删除特定的所有数据
    @Override
    public void removeValAll(int val) {
        checknull();

        if (isEmpty()) {
            return;
        }

        ListNode cur=head.next;

        ListNode pre=head;

        while (cur != null) {
            if (cur.val == val) {
                cur=cur.next;
            } else {

                pre.next=cur;
                pre=pre.next;
                cur=cur.next;
            }
        }

        pre.next=null;

        if (head.val==val) {
            removeFirst();
        }
    }


//    //删除单链表中所有的keyword
方法一:
//    public void removeValAll(int val){
//        ListNode cur=head;
//
//        while(cur.next!=null){
//            if(cur.next.val==val){
//                ListNode ret=cur.next;
//                cur.next=ret.next;//这里ret.next和直接写cur.next.next是一样的;
//            } else {
//                cur=cur.next;
//
//            }
//            if(cur==null){
//                break;
//            }
//        }
//
//        if(head.val==val){
//            head=head.next;
//        }
//    }



    // 搜索是否含有该数据

    @Override
    public boolean contains(int val) {

      checknull();
      ListNode cur=head;

      while (cur != null) {
          if (cur.val==val) {
              return true;
          }
          cur=cur.next;
      }
      return false;
    }



    @Override
    public void modify(int pos, int val) {
        checknull();

        if (isEmpty()) {
            return;
        }

        ListNode des=indexFind(pos);

        if (des==null) {
            return;
        }

        des.val=val;
    }

    @Override
    public void clear() {
        head=null;
    }

    private void  checknull() {
        if (head==null) {
            System.out.println("单链表为null");
        }
    }



    private  ListNode indexFind(int pos) {

      try {
          chackIdex(pos);
      }catch (IndexOutOfBoundsException e) {
          e.printStackTrace();
          return null;
      }

      ListNode cur=head;
      for (int i = 0; i < pos; i++) {
            cur=cur.next;
      }

      return cur;
    }



    @Override
    public int length() {
      int count=0;
      ListNode cur=head;
        while (cur != null) {
            count++;
            cur=cur.next;
        }

        return count;
    }



// 检查链表是否长度为 0

    private  boolean isEmpty() {
      return length()==0;
    }



    // 检查下标是否合法

    private void chackIdex(int pos) throws IndexOutOfBoundsException {
      if (pos <0 || pos >= length()) {
          throw  new  IndexNotLegalException();
      }
    }



}

在这里插入图片描述

是不是看着眼花缭乱的,不妨不妨下面让小编来细细讲解一下我们 增删查改 的主要内容吧 💥💥💥

<1>. 增加功能

指定位置 插入为例

 // 指定位置插入
    @Override
    public void insert(int pos, int val) {

        checknull();

        if (pos==0) {
            insertFirst(val);
            return;
        }

        if (pos==length()) {
            insertLast(val);
            return;
        }

        ListNode des= indexFind(pos);
        if (des==null) {
            return;
        }

        ListNode cur=head;
        while (cur.next != des) {
            cur=cur.next;
        }

        ListNode node=new ListNode(val);

        node.next=des;
        cur.next=node;

    }

我们先找到 pos 位置,把新的 nodenext 修改成修改指向 pos 位置的节点的

在将 pos-1 位置的 next 修改指向为 node

请添加图片描述

鱼式疯言

在插入中需要特别考虑以下三种情况

  1. pos 可能不合法
  try {
      chackIdex(pos);
  }catch (IndexOutOfBoundsException e) {
      e.printStackTrace();
      return null;
  }
  1. 头位置 插入
if (pos==0) {
    insertFirst(val);
    return;
}
  1. 尾位置 插入
  if (pos==length()) {
        insertLast(val);
        return;
    }

<2>. 删除功能

指定找到 pos 位置,并把 pos-1 的节点和 pos+1 的节点用 next 进行连接

@Override
    public void remove(int pos) {

      checknull();

        if (isEmpty()) {
            return;
        }

        if (pos==0) {
            removeFirst();
            return;
        }

        ListNode dec=indexFind(pos);

        if (dec==null) {
            return;
        }
        ListNode cur=head;


        while (cur.next !=dec) {
            cur=cur.next;
        }

        cur.next=cur.next.next;

    }

请添加图片描述

鱼式疯言

需要注意的点

  1. 当pos 位置不合法时
  try {
      chackIdex(pos);
  }catch (IndexOutOfBoundsException e) {
      e.printStackTrace();
      return null;
  }
  1. 如果链表为空 时
 if (isEmpty()) {
        return;
    }
  1. 头部位置删除时
 if (pos==0) {
        removeFirst();
        return;
    }

<3>. 查找功能

查找功能主要是查找是否含有该数据以及下标的功能

主要过程是先 从头节点开始遍历 ,当找到该数据就返回 true下标位置

// 搜索是否含有该数据

@Override
public boolean contains(int val) {

  checknull();
  ListNode cur=head;

  while (cur != null) {
      if (cur.val==val) {
          return true;
      }
      cur=cur.next;
  }
  return false;
}

请添加图片描述

是的

这里就可以 很清楚的寻找到对应数据的位置

鱼式疯言

如果数据为 ,我们就不需要修改

<4>. 修改功能

主要过程是先 从头节点开始遍历 ,当找到该数据就返回 下标位置

然后找到该小标位置就返回该节点,对这个 节点 的数据进行 修改

@Override
public void modify(int pos, int val) {
    checknull();

    if (isEmpty()) {
        return;
    }

    ListNode des=indexFind(pos);

    if (des==null) {
        return;
    }

    des.val=val;
}

鱼式疯言

如果链表为 ,我们就 不需要修改

if (des==null) {
    return;
}

基本单链表的的框架我们讲完了,但小爱同学就思考了,我们这种链表在val
中只能放整型数据么? 不可以放其他类型的数据吗?

答案自然是 可以的

3.其他处理

  • 自定义一个异常来检查下标合法性
package singlinklist;
public class IndexNotLegalException extends RuntimeException{

    public IndexNotLegalException() {

    }

    public IndexNotLegalException(String message) {
        super(message);
    }
}
  • 主函数逻辑的实现
package singlinklist;

public class Test {

    public static void main(String[] args) {
        ISingleLinkList msl =new MySingleLinkedList();

        // 插入
        System.out.println("=====插入========");

        // 尾插

        msl.insertFirst(1);




        msl.insertLast(1);
        msl.insertLast(1);
        msl.insertLast(1);
        msl.insertLast(1);
        msl.insertLast(6);
        msl.insertLast(1);
        msl.insertLast(1);
        msl.insertLast(2);
        msl.insertLast(1);
        msl.insertLast(3);
        msl.insertLast(1);
        msl.insertLast(1);

        msl.display();


//        System.out.println("======删除=======");
//
//        msl.remove(3);
//        msl.removeFirst();
//        msl.removeLast();
//        msl.display();
//
//
//        System.out.println("======修改=====");
//        msl.modify(1,2);
//        msl.display();
//
//
//        System.out.println("=====查找=====");
//        System.out.println(msl.contains(2));
//        System.out.println(msl.contains(3));
//        System.out.println(msl.length());
//
//        msl.clear();

        System.out.println("=======");
//        msl.removeVal(0);
//        msl.removeVal(1);
//        msl.removeVal(2);
//        msl.removeVal(3);
//        msl.display();

        msl.removeValAll(1);

        msl.display();


        msl.insertLast(2);
        msl.insertLast(3);

        msl.insert(3,9);
        msl.insertFirst(0);
        msl.display();


        System.out.println("======删除=======");

        msl.remove(3);
        msl.removeFirst();
        msl.removeLast();
        msl.display();


        System.out.println("======修改=====");
        msl.modify(1,2);
        msl.display();


        System.out.println("=====查找=====");
        System.out.println(msl.contains(2));
        System.out.println(msl.contains(3));
        System.out.println(msl.length());

        msl.clear();



    }
}

三. 单链表的优化

单链表如果 限定死了 ,只能存放 整型或者 浮点型 那就太单一了

所以如果我们要对 单链表优化 的话,那么我们不得不请出我们的 泛型

1.功能接口

package generarraysinglinklist;

public interface IGSingleLinkList<T> {


    // 打印数据
    public void display();

    // 尾删数据
    public void removeLast();

    // 头删
    public void removeFirst();

    // 指定位置删除数据
    public void remove(int pos);


    // 删除指定数据
    public void removeVal(T val);

    // 删除指定的所有数据
    public void removeValAll(T val);

    // 头插
    public void insertFirst(T val);

    // 尾插数据
    public void insertLast(T val);

    // 指定位置插入数据
    public void insert(int pos,T val);

    // 确定数据是否存在
    public boolean contains(T val);

    // 修改数据
    public void modify(int pos ,T val);

    // 清空单链表
    public void clear();


    // 链表长度
    public int length();

}

2. 功能实现

package generarraysinglinklist;

import singlinklist.ISingleLinkList;
import singlinklist.IndexNotLegalException;

public class GMySingleLinkedList<T> implements IGSingleLinkList<T> {


    public ListNode head;

  public static  class ListNode<T> {

        // 存放数据
        public  T val;

        // 指向下一个节点的next
        public ListNode<T> next;

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

    public GMySingleLinkedList(T val) {

        this.head = new ListNode<T>(val);
    }


    // 打印单链表
    @Override
    public void display() {

     checknull();

      ListNode cur=head;

      while (cur != null) {
          System.out.print(cur.val+" ");
          cur=cur.next;
      }

        System.out.println();


    }



    @Override
    public void insertFirst(T val) {
        checknull();


        ListNode node=new ListNode(val);

        node.next=head;
        head=node;

    }


    @Override
    public void insertLast(T val) {
        checknull();

        ListNode cur=head;

        while (cur.next !=null) {
            cur=cur.next;
        }

        ListNode node =new ListNode(val);

//       本身 cur.next=null  这行可加可不加
//        node.next=cur.next;

        cur.next=node;


    }


    // 指定位置插入
    @Override
    public void insert(int pos, T val) {

        checknull();

        if (pos==0) {
            insertFirst(val);
            return;
        }

        if (pos==length()) {
            insertLast(val);
            return;
        }

        ListNode des= indexFind(pos);
        if (des==null) {
            return;
        }

        ListNode cur=head;
        while (cur.next != des) {
            cur=cur.next;
        }

        ListNode node=new ListNode(val);

        node.next=des;
        cur.next=node;

    }



    @Override
    public void removeLast() {
      checknull();

      if (isEmpty()) {
          return;

      }

      ListNode cur=head;

      if (cur.next==null) {
          head=null;
          return;
      }

        while (cur.next.next != null) {
            cur=cur.next;
        }

        cur.next=null;

    }

    @Override
    public void removeFirst() {
        checknull();

        if (isEmpty()) {
            return;
        }

        ListNode cur=head;

        head=head.next;

        cur=null;
    }


    @Override
    public void remove(int pos) {

      checknull();

        if (isEmpty()) {
            return;
        }

        if (pos==0) {
            removeFirst();
            return;
        }

        ListNode dec=indexFind(pos);

        if (dec==null) {
            return;
        }
        ListNode cur=head;


        while (cur.next !=dec) {
            cur=cur.next;
        }

        cur.next=cur.next.next;

    }




    // 删除特定数据
    @Override
    public void removeVal(T val) {
      checknull();

      if (isEmpty()) {
          return;
      }

      ListNode cur=head;

      if (cur.val.equals(val)) {
            removeFirst();
            return;
      }


      while (cur.next != null) {

          if (cur.next.val.equals(val)) {
            cur.next=cur.next.next;
            return;
          }

          cur=cur.next;

      }


  }


    // 删除特定的所有数据
    @Override
    public void removeValAll(T val) {
        checknull();

        if (isEmpty()) {
            return;
        }

        ListNode cur=head.next;

        ListNode pre=head;

        while (cur != null) {
            if (cur.val .equals(val) ) {
                cur=cur.next;
            } else {

                pre.next=cur;
                pre=pre.next;
                cur=cur.next;
            }
        }

        pre.next=null;

        if (head.val.equals(val)) {
            removeFirst();
        }
    }


//    //删除单链表中所有的keyword
方法一:
//    public void removeValAll(int val){
//        ListNode cur=head;
//
//        while(cur.next!=null){
//            if(cur.next.val.equals(val)){
//                ListNode ret=cur.next;
//                cur.next=ret.next;//这里ret.next和直接写cur.next.next是一样的;
//            } else {
//                cur=cur.next;
//
//            }
//            if(cur==null){
//                break;
//            }
//        }
//
//        if(head.val.equals(val)){
//            head=head.next;
//        }
//    }



    // 搜索是否含有该数据

    @Override
    public boolean contains(T val) {

      checknull();
      ListNode cur=head;

      while (cur != null) {
          if (cur.val.equals(val)) {
              return true;
          }
          cur=cur.next;
      }
      return false;
    }



    @Override
    public void modify(int pos, T val) {
        checknull();

        if (isEmpty()) {
            return;
        }

        ListNode des=indexFind(pos);

        if (des==null) {
            return;
        }

        des.val=val;
    }

    @Override
    public void clear() {
      ListNode<T> cur=head;
      while (cur != null) {
          cur.val=null;
          cur=cur.next;
      }
        head=null;
    }

    private void  checknull() {
        if (head==null) {
            System.out.println("单链表为null");
        }
    }



    private  ListNode indexFind(int pos) {

      try {
          chackIdex(pos);
      }catch (IndexOutOfBoundsException e) {
          e.printStackTrace();
          return null;
      }

      ListNode cur=head;
      for (int i = 0; i < pos; i++) {
            cur=cur.next;
      }

      return cur;
    }



    @Override
    public int length() {
      int count=0;
      ListNode cur=head;
        while (cur != null) {
            count++;
            cur=cur.next;
        }

        return count;
    }



// 检查链表是否长度为 0

    private  boolean isEmpty() {
      return length()==0;
    }



    // 检查下标是否合法

    private void chackIdex(int pos) throws IndexOutOfBoundsException {
      if (pos <0 || pos >= length()) {
          throw  new IndexNotLegalException();
      }
    }



}

3. 其他处理

package generarraysinglinklist;

import generarraylist.GMyArrayList;
import generarraylist.IGList;

import java.util.List;


public class Test {
    public static void main(String[] args) {
        IGSingleLinkList<String> c=new GMySingleLinkedList<>("1");
        System.out.println("--------增加数据----------");
        c.insertLast("1");
        c.insertLast("3");
        c.insert(1,"2");
        c.insert(1,"2");
        c.insert(1,"2");
        c.insert(1,"2");
        c.insert(1,"2");
        c.insert(1,"2");
        c.insert(1,"2");
        c.insertFirst("0");
        c.display();

        System.out.println("--------删除数据-----------");



        c.removeValAll("2");
        c.removeLast();
        c.display();


        System.out.println("--------查找数据-------------");

        String str= "0";

       boolean b= c.contains(str);
       System.out.println(b);


        System.out.println("---------修改数据-----------");
        c.modify(1,"2");
        c.display();


    }
}

在这里插入图片描述

  • 自定义一个异常来检查下标合法性
package singlinklist;
public class IndexNotLegalException extends RuntimeException{

    public IndexNotLegalException() {

    }

    public IndexNotLegalException(String message) {
        super(message);
    }
}

在前面小编已经详细介绍了 底层原理 ,这里小编就 不重复赘述 了,

心细的小伙伴是不是发现了只需要把 int 类型改成 T 即可完成我们的需求

具体泛型的理解期待博主下一篇文章的详解哦,在这里小伙伴们只需要记住一点:

泛型是可以接收并使用任何类型的

总结

  1. 链表的初识: 从我们的ArrayList 引出我们链表的概念以及多种结构的了解
  2. 单链表的实现: 单链表节点如何实现创建和连接并进行增删查改的详细说明
  3. 单链表的优化: 我们讲解了泛型的引入可以使单链表的可以增加不同类型的

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

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

相关文章

时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测

时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测 目录 时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测&#xff08;完整源码和数据…

算法学习——LeetCode力扣动态规划篇6

算法学习——LeetCode力扣动态规划篇6 121. 买卖股票的最佳时机 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&…

三元组数据模型:构建知识图谱的基石

目录 前言1. 三元组数据模型概述1.1 定义与结构1.2 特点 2. 三元组在知识图谱中的应用2.1 知识表示2.2 知识推理2.3 数据整合 3 三元组的数据格式3.1 N-Triples &#xff1a;3.2 RDF/XML &#xff1a;3.3 Turtle &#xff08;又称为 Terse RDF Triple Language&#xff09;&…

编程语言|C语言——数组与指针

一、数组 同一类型的变量——元素&#xff08;element&#xff09;集中在一起&#xff0c;在内存上排列成一条直线&#xff0c;这就是数组&#xff08;array&#xff09;。 1.1 一维数组 一维数组的声明 int arr1[10]; int arr2[2 8];#define N 10 int arr3[N];int count 10;…

JavaScript的学习笔记

<script src"index.js" defer></script>&#xff0c;defer的作用是延迟加载index.js文件 定义变量 变量的类型分为两大类&#xff1a;基本类型和复合类型 JavaScript是一种弱类型语言&#xff0c;所以没有强类型语言所具有的int,float,char等等&#x…

无药可医还能怎么办?越没本事的人,越喜欢从别人身上找原因!——早读(逆天打工人爬取热门微信文章解读)

无药可医的病该怎么办呢&#xff1f; 引言Python 代码第一篇 洞见 《骆驼祥子》&#xff1a;越没本事的人&#xff0c;越喜欢从别人身上找原因第二篇 人民日报 来啦 新闻早班车要闻社会政策 结尾 “吾日三省吾身&#xff0c;而后深知自助者天助之。” 在人生的迷宫中 遭遇困境时…

域环境共享文件夹,容量配额管理

首先&#xff0c;我们先创建一个新的磁盘&#xff0c;必须在服务器关机的状态下创建&#xff0c;只有在关机状态下才能创建NVMe类型的磁盘。 打开此电脑&#xff0c;右击创建的磁盘&#xff0c;点击属性。 点击共享&#xff0c;点击高级共享。 将共享此文件夹勾选上&#xff0c…

蓝桥杯 第2945题 课程抢购 C++ Java Python

目录 题目 思路和解题方法 c 代码 Java 版本&#xff08;仅供参考&#xff09; Python 版本&#xff08;仅供参考&#xff09; 代码细节&#xff1a; C 代码细节解释: Python 代码细节解释: lenyan算法笔记 语雀 《lenyan算法笔记》 个人笔记日常更新。含金量不高。/…

ZNC3罗德与施瓦茨ZNC3网络分析仪

181/2461/8938产品概述&#xff1a; 罗德与施瓦茨 ZNC3 网络分析仪的工作频率范围为 9 kHz 至 3 GHz&#xff0c;面向移动无线电和电子产品行业的应用。它具有双向测试装置&#xff0c;用于测量有源和无源 DUT 的所有四个 S 参数。此外&#xff0c;它还提供适合开发和生产中各…

2023年第十四届蓝桥杯大赛软件类省赛C/C++研究生组真题(代码完整题解)

C题-翻转⭐ 标签:贪心 简述:如果 S 中存在子串 101 或者 010,就可以将其分别变为 111 和 000,操作可以无限重复。最少翻转多少次可以把 S 变成和 T 一样。 链接: 翻转 思路:要求步骤最少->S每个位置最多修改一次->从头开始遍历不匹配就翻转->翻转不了就-1 …

esp32中vscode的开发环境

vscode中安装esp32开发环境请参考&#xff1a;CSDN 1、调出esp32的控制面板View ->Command Paletter&#xff0c;或者快捷键&#xff08;ctrshitp&#xff09; 调出esp-idf的样例工程 选择ESP-IDF所在的安装路径 选择一个样例工程&#xff0c;作为工程模板 创建的新工程如…

基于springboot实现课程作业管理系统项目【项目源码+论文说明】

基于springboot实现课程作业管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;课程作业管理系统当然也不能排除在外。课程作业管理系统是以实际运用为开发背景…

swift中的autoreleasepool(自动释放池)有用么?

想到一个问题 swift中的autoreleasepool(自动释放池)有用么? 我们进行验证一下 首先我们写一个加载图片的方法,保证会真正用到真实的IMP内存func loadBigData(string: String?) {if let path Bundle.main.path(forResource: "big", ofType: "png") {for…

[数据库]windows环境安装mysql数据库服务

mysql介绍 MySQL是一个流行的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是由瑞典的MySQL AB公司开发&#xff0c;后来被Sun Microsystems收购&#xff0c;再后来Sun被Oracle收购。MySQL以其稳定性、可靠性、高性能和开放源代码的特性而闻名&#xff0c…

完整部署一套k8s-v.1.28.0版本的集群

一、系统情况 虚拟机版本&#xff1a;esxi 6.7 系统版本&#xff1a;centos7.9_2009_x86 配置&#xff1a;4核8G&#xff08;官网最低要求2核2G&#xff09; 192.168.0.137 master节点 192.168.0.139 node2节点 192.168.0.138 node1节点&#xff08;节点扩容练习&#xf…

剑指Offer题目笔记21(计数排序)

面试题74&#xff1a; 问题&#xff1a; ​ 输入一个区间的集合&#xff0c;将重叠的区间合并。 解决方案&#xff1a; ​ 先将所有区间按照起始位置排序&#xff0c;然后比较相邻两个区间的结束位置就能知道它们是否重叠。如果它们重叠就将它们合并&#xff0c;然后判断合并…

C++ namespace 使用梳理

前言 发现 namespace 这个小细节在工作项目中处理的有一点点小混乱&#xff0c;于是稍微梳理了一下关于 C namespace 使用相关的使用内容&#xff0c;为日后项目的重构做准备&#xff0c;虽然是很小的点&#xff0c;但是也是值得注意的&#xff0c;毕竟代码的质量体现在每一个…

Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(二)项目实现-第五篇-核心功能车票预定开发及nacos集成

本文参考自 Springboot3微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第&#xff08;二&#xff09;章——项目实现 的第五篇&#xff0c;本篇讲解该项目的核心功能——余票查询、车票预定功能的基础版开发&#xff0c;以及讲解项目与Nacos的集成…

linux 下固定摄像头的设备名字

为什么写着一篇文章 在做基于ARM-Linux的垃圾分类垃圾桶的时候&#xff0c;在不小心松动usb摄像头的或者是重新连接的时候&#xff0c;摄像头的编号会改变。有时候etc/udev/video2 &#xff0c;有时etc/udev/video3这样使得每次运行的时候都需要修改编号。 什么是udev规则 u…

Pillow教程03:图像处理的基本步骤+分离split+合并merge+混合blend+composite遮罩

--------------Pillow教程集合--------------- Python项目18&#xff1a;使用Pillow模块&#xff0c;随机生成4位数的图片验证码 Python教程93&#xff1a;初识Pillow模块&#xff08;创建Image对象查看属性图片的保存与缩放&#xff09; Pillow教程02&#xff1a;图片的裁剪…