当前位置: 首页 > news >正文

【数据结构初阶】第三节.顺序表详讲

文章目录

前言

一、顺序表的概念

二、顺序表功能接口概览

三、顺序表基本功能的实现

四、四大功能

1、增加数据 

1.1 头插法:

1.2 尾插法

1.3 指定下标插入 

2、删除数据

2.1 头删

2.2 尾删

2.3 指定下标删除

2.4 删除首次出现的指定元素

3、查找数据

3.1 获取指定位置的元素

3.2 获取指定元素所在的位置

3.3 查找表中是否包含某个元素

4、修改数据

4.1 修改表中任意位置的元素

五、代码总结

MyArraysList.java

Test.java

总结


前言

今天我们将开始学习数据结构的第一个重点知识,顺序表的学习;顺序表是我们学习数据结构的第一个重点,一定要认真掌握,为后面其他的数据结构打下坚实的基础;

那就让我们进入到今天的课程当中吧!!!!!!!!!


一、顺序表的概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构;

一般情况下采用数组存储,在数组上完成数据的增删查改。

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。(本篇主要围绕静态顺序表展开)
  2. 动态顺序表:使用动态开辟的数组存储。

二、顺序表功能接口概览

本文将创建两个Java文件:MyArraysList.java用于顺序表的实现,Test.java用于顺序表的各个接口的测试

代码示例:

​
import java.util.Arrays;public class MyArraysList {private int[] elem;private int usedSize; // 默认值是0private static final int DEFAULT_SIZE = 4; // 定义为常量,更加安全// 初始化顺序表public MyArraysList() {this.elem = new int[4];}// 对顺序表进行扩容public void expand() {}//判断当前顺序表是否为空public boolean isempty() {}// 判断当前顺序表是不是满了public boolean isFull() {}// 打印顺序表public void display() {}// 新增元素,默认在数组最后新增public void add(int data) {}// 新增元素,在数组最前面新增public void addHead(int data){}// 在 pos 位置新增元素public void addPos(int pos, int data) {}// 删除表头元素public void removeHead() {}// 删除表尾元素public void removeTail() {}// 指定下标元素的删除public void removePos(int pos) {}//删除第一次出现的关键字keypublic void remove(int toRemove) {}// 判定是否包含某个元素public boolean contains(int toFind) { return true; }// 查找某个元素对应的位置public int indexOf(int toFind) { return -1; }// 获取 pos 位置的元素public int getPos(int pos) { return -1; }// 给 pos 位置的元素设为 valuepublic void setPos(int pos, int value) {}// 获取顺序表长度public int size() { return 0; }// 清空顺序表public void clear() {}
}​

说明:

private int[] elem;

elem指的是新建立的一个数组;

private int usedSize; // 默认值是0

usedSize指的是数组的有效的长度;(即存储了元素的长度是多少)

private static final int DEFAULT_SIZE = 4; // 定义为常量,更加安全

并且数组的初始化的长度为4;

上述就为顺序表的一些基本实现方法;接下来我们将逐个的讲解这些方法具体是怎么实现的;


三、顺序表基本功能的实现

功能1:

对顺序表进行扩容

// 对顺序表进行扩容public void expand() {this.elem = Arrays.copyOf(this.elem, this.usedSize * 2);System.out.println("已经成功扩容至原来的两倍"); // 给用户提醒}

解析:

首先我们要知道Arrays中copyOf方法的用法;

Arrays.copyOf方法:

概念:

Arrays.copyOf()的实质其实就是改变数组的长度,实现数组的扩容和缩容。

语法格式:

Arrays.copyOf(original,newLength);original:需要改变的数组名newLength:数组改变后新的长度

代码示例说明:

public static void main(String[] args) {//定义一个初始数组,初始数组的长度为8int[] a = {1,2,3,4,5,6,7,8};System.out.println("源数组:"+Arrays.toString(a));//数组扩容,将数组的长度由8扩展为10a = Arrays.copyOf(a, 10);System.out.println("缩容后的数组:"+Arrays.toString(a));}

输出结果:

最后我们就通过这个Arrays中copyOf方法完成了扩容的操作;


功能2:

判断顺序表是否为空 

     /*** 判断当前顺序表是否为空* @return true->空的,false->还没空*/public boolean isempty() {if (this.usedSize == 0) {return true;}else return false;}

解析:

usedSize表示顺序表的有效长度;所以通过判断usedSize是否为0来实现判断顺序表是否为空的代码实现;


功能3:

判断顺序表是否已满:

    /*** 判断当前顺序表是不是满了* @return true->满了,false->还没满*/public boolean isFull() {if (this.usedSize == this.elem.length) return true;else return false;}

解析:
此处的elem.length表示的是数组的长度;当数组的长度等于顺序表的有效长度时;

则说明此顺序表是满的;


功能4:

打印顺序表:

// 打印顺序表
// 打印的第一种方式public void display() {for (int i = 0; i < this.elem.length; i++) {System.out.print(this.elem[i] + " ");}System.out.println();}
// 打印的第二种方式,用Arrays.toString直接打印public void display() {System.out.println(Arrays.toString(this.elem));}

解析:

此处通过数组下标的方式来遍历数组;用数组下标与数组的长度对比;

由此来遍历整个顺序表;从而实现打印顺序表;

图示解析:


功能5:

获取顺序表的有效长度:

 // 获取顺序表的有效长度
public int size() {return this.usedSize;
}

解析:

直接返回有效长度usedSize即可;


功能6:

清空顺序表

 // 清空顺序表public void clear() {for (int i = 0; i < this.usedSize; i++) {this.elem[i] = 0;}this.usedSize = 0; // 注意有效数组长度也要清零}

解析:

此处的清空顺序表和前面的打印顺序表不一样;

清空顺序表只需要将顺序表里面的有效长度清除即可,不用遍历整个顺序表;

最后注意要将有效数组长度也清零;

图示解析:

四、四大功能

1、增加数据 

1.1 头插法:

1 // 新增元素,在数组最前面新增public void addHead(int data) {if (isFull()) {System.out.println("数组满了,需要扩容");expand();}else {// 从usedSize下标开始,不会数组越界(此时的elem.length > usedSize)for (int i = this.usedSize; i > 0; --i) {this.elem[i] = this.elem[i - 1]; // 从后往前挪动数据,为的是给顺序表的表头腾出来}this.elem[0] = data; // 在顺序表开头插入this.usedSize++;    // 数组有效长度加一}

解析:

1.

在顺序表中插入元素,首先要先 判断顺序表是否满了;

如果满了,需要扩容;如果没有满,则进行插入操作;

所以此处就需要用到前面介绍过的public boolean isFull函数;

代码示例:

if (isFull()) {System.out.println("数组满了,需要扩容");expand();

2.既然实在开头插入,那我们就应该把顺序表中每一个元素向后移动一位,把第一个位置腾空出来,再将需要的数据插入进去;

移动时肯定是先移动后面的元素,然后依次移动前一个元素;

代码示例:

for (int i = this.usedSize; i > 0; --i) {this.elem[i] = this.elem[i - 1]; // 从后往前挪动数据,为的是给顺序表的表头腾出来}

此代码就是实现顺序表中代码依次往后挪动的操作;

图片示例:


1.2 尾插法

//在数组最后新增public void addTail(int data) {if (isFull()) {System.out.println("数组满了需要扩容");expand();}else this.elem[this.usedSize] = data;this.usedSize++;}

解析:

1.

插入操作首先要需要 判断顺序表是否满了;

同上面的头插法;

2.

既然是尾插法,就不需要进行元素的移动,直接在有效数据长度的后面插入数据即可;

最后要注意将有效数据长度增加一位(因为多存储了一个数据)

代码示例:

this.elem[this.usedSize] = data;this.usedSize++;

1.3 指定下标插入 

// 在 pos 位置新增元素public void addPos(int pos, int data) {if (pos < 0 || pos > usedSize) {System.out.println("pos位置不合法"); return;}if (isFull()) {System.out.println("数组满了需要扩容");expand();}else {// 如果插入位置在顺序表的中间,要注意挪动元素,从后向前挪动,这样不会造成元素值的覆盖for (int i = this.usedSize - 1; i >= pos; --i) {this.elem[i + 1] = this.elem[i];}this.elem[pos] = data; // 挪动完毕,可以赋值插入this.usedSize++;      // 当前元素数加一}}

解题思路:

  1.  判断pos位置是否合法(在顺序表中,数据是连续的,中间不能有空缺)
  2.  判断顺序表是否满了,如果满了,需要扩容
  3.  插入数据(可能需要1.挪动数据2.插入数据)

注意:

解析:

1. 判断pos位置是否合法(在顺序表中,数据是连续的,中间不能有空缺)

代码示例:

if (pos < 0 || pos > usedSize) {System.out.println("pos位置不合法"); return;}

在数据结构中,每次储存元素必须有一个前驱信息的结点;所以pos>usedSIze;

2.判断顺序表是否满了,如果满了,需要扩容;

这里和上面头插尾插一样,不过多赘述;

3.插入数据(可能需要1.挪动数据2.插入数据)

代码示例:

 // 如果插入位置在顺序表的中间,要注意挪动元素,从后向前挪动,这样不会造成元素值的覆盖for (int i = this.usedSize - 1; i >= pos; --i) {this.elem[i + 1] = this.elem[i];}this.elem[pos] = data; // 挪动完毕,可以赋值插入this.usedSize++;      // 当前元素数加一

图示说明:

当pos=2时;


2、删除数据

2.1 头删

 // 删除表头元素public void removeHead() {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}// 从第一个元素开始,用后面元素的值覆盖掉前面的值,遍历整个数组就相当于把第一个元素用覆盖的方式抹去了for (int i = 1; i < this.usedSize; i++) {this.elem[i - 1] = this.elem[i];}this.elem[this.usedSize - 1] = 0; // 现在的最后一个元素是原来的倒数第二个元素, 所以原来的最后一个有效元素要置0this.usedSize--; // 不要忘记改变有效数组的长度}

解题思路:

首先还是要判断顺序表是否为空的问题;

要想删除第一个元素,我们可以通过从从第一个元素开始,用后面元素的值覆盖掉前面的值,遍历整个数组就相当于把第一个元素用覆盖的方式抹去了;

现在的最后一个元素是原来的倒数第二个元素, 所以原来的最后一个有效元素要置0;

最后不要忘记改变有效数组的长度;

图示说明:


2.2 尾删

    // 删除表尾元素public void removeTail() {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}this.elem[this.usedSize - 1] = 0; // 直接将最后一个元素置0就完成了尾删this.usedSize--; // 不要忘记改变有效数组的长度}

解析:

首先还是判断顺序表是否为空;

然后既然尾删,那么直接将最后一个有效元素置0即可;elem[this.usedSize - 1] = 0;

最后不要忘记修改有效数组的长度;usedSize--;


2.3 指定下标删除

 // 指定下标元素的删除public void removePos(int pos) {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}if (pos < 0 || pos >= this.usedSize) {System.out.println("pos下标不合法");}else {for (int i = pos; i < this.usedSize ; i++) {this.elem[i-1] = this.elem[i]; // 从要删除的下标开始,用后边元素的值覆盖掉前面的值,就完成了删除}this.elem[this.usedSize - 1] = 0; // 要完整的删除,将挪动的最后一个元素的原本位置 置空this.usedSize--;// 删除后不要忘记更改顺序表的有效长度}}

解题思路:

  1. 判断pos位置是否合法(在顺序表中,数据是连续的,中间不能有空缺)
  2.  判断顺序表是否满了,如果满了,需要扩容
  3.  删除数据(覆盖数据)

解析:

此处和上面指定下标插入一样的讨论情况;

都是先判断合法和是否满了的情况;

最后通过和头删法一样的分析方法,来实现指定下标删除;


2.4 删除首次出现的指定元素

 //删除第一次出现的关键字keypublic void removeKey(int toRemove) {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toRemove) {// 注意是this.usedSize - 1,将此时 i 之后的元素统一往前搬移一个位置for (int j = i; j < this.usedSize - 1; ++j) {this.elem[j] = this.elem[j + 1];}this.elem[this.usedSize - 1] = 0; // 要完整的删除,将挪动的最后一个元素的原本位置 置空this.usedSize--; // 删除后不要忘记更改顺序表的有效长度return; // 只删除第一次出现的}}}


3、查找数据

3.1 获取指定位置的元素

 // 获取 pos 位置的元素public int getPos(int pos) {if (pos < 0 || pos >= this.usedSize) { // 注意这里当pos==this.usedSize也是不合法的,因为此时的pos下标所要获取的是顺序表中第usedSize+1个元素System.out.println("pos的位置不合法");return -1;}else {return this.elem[pos];}}

解题思路:

  1. 考虑要获取的位置是否合法
  2. 返回指定位置的元素

解析:

1.要获取这个元素,首先要判断这个元素的位置是否合法;

但此处要注意pos==this.usedSize也是不合法的;因为此时的pos下标所要获取的是顺序表中第usedSize+1个元素;

2.最后直接返回指定位置的元素即可;return this.elem[pos];


3.2 获取指定元素所在的位置

 // 查找某个元素所对应顺序表中的位置public int indexOf(int toFind) {for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toFind) {return i;}}System.out.println("在数组中没有找到该元素");return -1;}

解析:

既然要查找一个元素的位置,那么就应该遍历整个顺序表;

代码中的toFind指的是所要查找的元素;

当elem[i] == toFind时候,说明找到了所要查找的元素;否则提示顺序表中找不到所要查找的元素;


3.3 查找表中是否包含某个元素

 /*** /判定是否包含某个元素* @param toFind 要查找的元素* @return true->包含, false->不包含*/public boolean contains(int toFind) {for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toFind)  return true;}return false;}

解析:

直接对整个顺序表进行遍历;直到找到所需要找的那个元素为止;this.elem[i] == toFind;

当找到了return   ture;否则return  fales;


4、修改数据

4.1 修改表中任意位置的元素

// 给 pos 位置的元素设为 valuepublic void setPos(int pos, int value) {if (pos < 0 || pos > this.usedSize) {System.out.println("pos位置不合法");return;}if (pos == this.usedSize) { // 对这种情况要单独处理,此时相等于增加元素this.elem[pos] = value;this.usedSize++;}else {this.elem[pos] = value;}}

解题思路:

1.首先考虑修改的位置是否合法

2.考虑特殊情况

解析:

value指的是pos位置所放置的元素;

1.首先依旧需要考虑修改位置是否合法pos < 0 || pos > this.usedSize;

2.然后考虑特殊情况,当pos=this.usedSize时;

此时就相当于新增加了一个元素,类似于前面新增数据的尾插法;

、代码总结

MyArraysList.java

import java.util.Arrays;public class MyArraysList {private int[] elem;private int usedSize; // 默认值是0private static final int DEFAULT_SIZE = 4; // 定义为常量,更加安全// 初始化顺序表public MyArraysList() {this.elem = new int[4];}// 对顺序表进行扩容public void expand() {this.elem = Arrays.copyOf(this.elem, this.usedSize * 2);System.out.println("已经成功扩容至原来的两倍"); // 给用户提醒}/*** 判断当前顺序表是否为空* @return true->空的,false->还没空*/public boolean isempty() {if (this.usedSize == 0) {return true;}else return false;}/*** 判断当前顺序表是不是满了* @return true->满了,false->还没满*/public boolean isFull() {if (this.usedSize == this.elem.length) return true;else return false;}// 打印顺序表public void display() {for (int i = 0; i < this.elem.length; i++) {System.out.print(this.elem[i] + " ");}// System.out.println(Arrays.toString(this.elem));或者用Arrays.toString打印也行System.out.println();}// 新增元素,默认在数组最后新增public void addTail(int data) {if (isFull()) {System.out.println("数组满了需要扩容");expand();}else this.elem[this.usedSize++] = data;}// 新增元素,在数组最前面新增public void addHead(int data) {if (isFull()) {System.out.println("数组满了,需要扩容");expand();}else {// 从usedSize下标开始,不会数组越界(此时的elem.length > usedSize)for (int i = this.usedSize; i > 0; --i) {this.elem[i] = this.elem[i - 1]; // 从后往前挪动数据,为的是给顺序表的表头腾出来}this.elem[0] = data; // 在顺序表开头插入this.usedSize++;    // 数组有效长度加一}}// 1、判断pos位置是否合法(在顺序表中,数据是连续的,中间不能有空缺)// 2、判断顺序表是否满了,如果满了,需要扩容// 3、插入数据(可能需要挪作元素)// 在 pos 位置新增元素public void addPos(int pos, int data) {if (pos < 0 || pos > usedSize) {System.out.println("pos位置不合法"); return;}if (isFull()) {System.out.println("数组满了需要扩容");expand();}else {// 如果插入位置在顺序表的中间,要注意挪动元素,从后向前挪动,这样不会造成元素值的覆盖for (int i = this.usedSize - 1; i >= pos; --i) {this.elem[i + 1] = this.elem[i];}this.elem[pos] = data; // 挪动完毕,可以赋值插入this.usedSize++;      // 当前元素数加一}}// 删除表头元素public void removeHead() {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}// 从第一个元素开始,用后面元素的值覆盖掉前面的值,遍历整个数组就相当于把第一个元素用覆盖的方式抹去了for (int i = 1; i < this.usedSize; i++) {this.elem[i - 1] = this.elem[i];}this.elem[this.usedSize - 1] = 0; // 现在的最后一个元素是原来的倒数第二个元素, 所以原来的最后一个有效元素要置0this.usedSize--; // 不要忘记改变有效数组的长度}// 删除表尾元素public void removeTail() {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}this.elem[this.usedSize - 1] = 0; // 直接将最后一个元素置0就完成了尾删this.usedSize--; // 不要忘记改变有效数组的长度}// 指定下标元素的删除public void removePos(int pos) {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}if (pos < 0 || pos >= this.usedSize) {System.out.println("pos下标不合法");}else {for (int i = pos; i < this.usedSize - 1; ++i) {this.elem[i] = this.elem[i + 1]; // 从要删除的下标开始,用后边元素的值覆盖掉前面的值,就完成了删除}this.elem[this.usedSize - 1] = 0; // 要完整的删除,将挪动的最后一个元素的原本位置 置空this.usedSize--;// 删除后不要忘记更改顺序表的有效长度}}//删除第一次出现的关键字keypublic void removeKey(int toRemove) {if (isempty()) {System.out.println("顺序表为空,删除不合法");return;}for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toRemove) {// 注意是this.usedSize - 1,将此时 i 之后的元素统一往前搬移一个位置for (int j = i; j < this.usedSize - 1; ++j) {this.elem[j] = this.elem[j + 1];}this.elem[this.usedSize - 1] = 0; // 要完整的删除,将挪动的最后一个元素的原本位置 置空this.usedSize--; // 删除后不要忘记更改顺序表的有效长度return; // 只删除第一次出现的}}}/*** /判定是否包含某个元素* @param toFind 要查找的元素* @return true->包含, false->不包含*/public boolean contains(int toFind) {for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toFind)  return true;}return false;}// 查找某个元素对应的位置public int indexOf(int toFind) {for (int i = 0; i < this.usedSize; i++) {if (this.elem[i] == toFind) {return i;}}System.out.println("在数组中没有找到该元素");return -1;}// 获取 pos 位置的元素public int getPos(int pos) {if (pos < 0 || pos >= this.usedSize) {System.out.println("pos的位置不合法");return -1;}else {return this.elem[pos];}}// 给 pos 位置的元素设为 valuepublic void setPos(int pos, int value) {if (pos < 0 || pos > this.usedSize) {System.out.println("pos位置不合法");return;}if (pos == this.usedSize) { // 对这种情况要单独处理,此时相等于增加元素this.elem[pos] = value;this.usedSize++;}else {this.elem[pos] = value;}}// 获取顺序表长度public int size() {return this.usedSize;}// 清空顺序表public void clear() {for (int i = 0; i < this.usedSize; i++) {this.elem[i] = 0;}this.usedSize = 0; // 注意有效数组长度也要清零}}

Test.java

/*** 对顺序表进行测试的代码*/
public class Test {public static void main(String[] args) {MyArraysList myArraysList = new MyArraysList();// 尾插四个数字myArraysList.addTail(12);myArraysList.addTail(32);myArraysList.addTail(17);myArraysList.addTail(32);// 进行扩容myArraysList.expand();// 指定在pos位置新增元素myArraysList.addPos(1, 777);// 打印当前的顺序表System.out.print("第一次测试的顺序表为:");myArraysList.display();// 删除顺序表中首次出现的元素32myArraysList.removeKey(32);// 获取顺序表中 1下标的元素值int tmp = myArraysList.getPos(1);System.out.println("顺序表中下标为1的元素的值为:" + tmp);// 给顺序表中1下标的元素设为valuemyArraysList.setPos(1, 100);// 打印此时的顺序表System.out.print("修改后第二次测试的顺序表为:"); // 此时1下标的值为100myArraysList.display();// 顺序表此时的有效长度System.out.println("顺序表的有效长度为:" + myArraysList.size());// 清空顺序表myArraysList.clear();System.out.print("第三次测试的顺序表为:");myArraysList.display();System.out.println("清空顺序表后,顺序表的有效长度为:" + myArraysList.size());}}

测试结果:

总结

今天我们学习了数据结构的第一种顺序表的学习,下一节内容我们将进入到链表的学习,本节学习会让我们为后面的学习打下好的基础,所以说必须要能够熟练的掌握!!!!!!!!!!

 

相关文章:

【数据结构初阶】第三节.顺序表详讲

文章目录 前言 一、顺序表的概念 二、顺序表功能接口概览 三、顺序表基本功能的实现 四、四大功能 1、增加数据 1.1 头插法&#xff1a; 1.2 尾插法 1.3 指定下标插入 2、删除数据 2.1 头删 2.2 尾删 2.3 指定下标删除 2.4 删除首次出现的指定元素 3、查找数据…...

新手小白适合做跨境电商吗?

今天的跨境电商已经逐渐成熟&#xff0c;靠运气赚钱的时代早已过去&#xff0c;馅饼不可能从天上掉下来&#xff0c;尤其是你想做一个没有货源的小白劝你醒醒。做跨境电商真的不容易&#xff0c;要想做&#xff0c;首先要分析自己是否适合做。米贸搜整理了以下资料&#xff0c;…...

Python搭建自己[IP代理池]

IP代理是什么&#xff1a;ip就是访问网页数据服务器位置信息&#xff0c;每一个主机或者网络都有一个自己IP信息为什么要使用代理ip&#xff1a;因为在向互联网发送请求中&#xff0c;网页端会识别客户端是真实用户还是爬虫程序&#xff0c;在今天以互联网为主导的世界中&#…...

pandas——plot()方法可视化

pandas——plot()方法可视化 作者&#xff1a;AOAIYI 创作不易&#xff0c;如果觉得文章不错或能帮助到你学习&#xff0c;记得点赞收藏评论哦 在此&#xff0c;感谢你的阅读 文章目录pandas——plot()方法可视化一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤…...

【Three.js基础】坐标轴辅助器、requestAnimationFrame处理动画、Clock时钟、resize页面尺寸(二)

&#x1f431; 个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff1a;vue3从入门…...

C++之完美转发、移动语义(forward、move函数)

完美转发1. 在函数模板中&#xff0c;可以将自己的参数“完美”地转发给其它函数。所谓完美&#xff0c;即不仅能准确地转发参数的值&#xff0c;还能保证被转发参数的左、右值属性不变。2. C11标准引入了右值引用和移动语义&#xff0c;所以&#xff0c;能否实现完美转发&…...

LeetCode刷题系列 -- 48. 旋转图像

给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。示例 1&#xff1a;输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]输出&#…...

在多线程环境下使用哈希表

一.HashTable和HashMapHashTable是JDK1.0时创建的&#xff0c;其在创建时考虑到了多线程情况下存在的线程安全问题&#xff0c;但是其解决线程安全问题的思路也相对简单&#xff1a;在其众多实现方法上加上synchronized关键字&#xff08;效率较低&#xff09;&#xff0c;保证…...

【排序算法】堆排序(Heap Sort)

堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构&#xff0c;并同时满足堆积的性质&#xff1a;即子结点的键值或索引总是小于&#xff08;或者大于&#xff09;它的父节点。堆排序介绍学习堆排序之前&#xff0c;有必要了解堆&#xff01;若…...

分类预测 | Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测

分类预测 |Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测 目录分类预测 |Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测分类效果基本介绍模型描述程序设计参考资料分类效果 基本介绍 Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机…...

Allegro如何添加ICT操作指导

Allegro如何添加ICT操作指导 当PCB板需要做飞针测试的时候,通常需要在PCB设计的时候给需要测试的网络添加上ICT。 如图: Allegro支持给网络添加ICT,具体操作如下 首先在库中创建一个阻焊开窗的过孔,比如via10-ict一般阻焊开窗的尺寸比盘单边大2mil 在PCB中选择Manufacture…...

软件架构设计(二)——领域架构、基于架构的软件开发方法

目录 一、架构描述语言 ADL 二、特定领域软件架构 DSSA 三、DSSA的三层次架构模型 . 四、基于架构的软件开发方法 (1)基于架构的软件设计(ABSD) (2)开发过程 一、架构描述语言 ADL ADL是一种形式化语言&#xff0c;它在底层语义模型的支持下&#xff0c;为软件系统概念体…...

数组常用方法(2)---数组遍历方法

1. forEach(cb) 回调函数中有三个参数&#xff0c;第一个是当前遍历项&#xff08;必须&#xff09;&#xff0c;第二个是索引&#xff0c;第三个是遍历的数组本身。forEach() 对于空数组不会执行回调函数。forEach()不会使用回调函数的返回值&#xff0c;返回值为undefined。…...

卸载Node.js

0 写在前面 无论您是因为什么原因要卸载Node.js都必须要卸载干净。 请阅读&#xff1a; 1 卸载步骤 1.1通过控制面板卸载node.js winR—>control.exe—>卸载程序—>卸载Node.js 等待—>卸载成功 1.2 删除安装时的nodejs文件夹 通过记忆或者Everthing搜索找…...

发表计算机SCI论文,会经历哪些过程? - 易智编译EaseEditing

一、选期刊。 一定要先选期刊。每本期刊都有自己的特色和方向&#xff0c;如果你的稿子已经成型&#xff0c;再去考虑期刊选择的问题&#xff0c;恐怕后期不是退稿就是要大面积修改稿子。 选期刊的标准没有一定的&#xff0c;主要是各单位都有自己的要求&#xff0c;当然小编…...

python中lambda的用法

1. lambada简单介绍 lambda 在Python编程中使用的频率非常高&#xff0c;我们通常提及的lambda表达式其实是python中的一类特殊的定义函数的形式&#xff0c;使用它可以定义一个匿名函数。即当你需要一个函数&#xff0c;但又不想费神去命名一个函数&#xff0c;这时候&#xf…...

网络安全协议(3)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.当前流行操作系统的安全等级 1.Windows的安全等级 什么是EAL…...

102.第十九章 MySQL数据库 -- MySQL的备份和恢复(十二)

5.备份和恢复 5.1 备份恢复概述 5.1.1 为什么要备份 灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景 参考链接: https://www.toutiao.com/a6939518201961251359/ 5.1.2 备份类型 完全备份,部分备份 完全备份:整个数据集 部分备份:只备份数…...

【C++】C++入门 类与对象(一)

类与对象&#xff08;一&#xff09;一、类的引入二、类的定义1、类的两种定义方式&#xff1a;2、成员变量命名规则的建议&#xff1a;三、类的访问限定符及封装1、访问限定符2、封装四、类的实例化1、类的实例化概念2、类对象的大小的计算五、this指针this指针的特性一、类的…...

笔记_js运算符

目录二进制相关运算符移位运算符<<>>&#xff5c;(位或运算)参考文档二进制相关运算符 移位运算符 移位运算就是对二进制进行有规律的移位。 tips:进制转换文档链接 << “<<”运算符执行左移位运算。在移位运算过程中&#xff0c;符号位始终保持不变…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...

13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析

LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

FTXUI::Dom 模块

DOM 模块定义了分层的 FTXUI::Element 树&#xff0c;可用于构建复杂的终端界面&#xff0c;支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

GC1808:高性能音频ADC的卓越之选

在音频处理领域&#xff0c;高质量的音频模数转换器&#xff08;ADC&#xff09;是实现精准音频数字化的关键。GC1808&#xff0c;一款96kHz、24bit立体声音频ADC&#xff0c;以其卓越的性能和高性价比脱颖而出&#xff0c;成为众多音频设备制造商的理想选择。 GC1808集成了64倍…...