当前位置: 首页 > 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;符号位始终保持不变…...

java面试题(十九) Mybatis

4.1 谈谈MyBatis和JPA的区别 参考答案 ORM映射不同&#xff1a; MyBatis是半自动的ORM框架&#xff0c;提供数据库与结果集的映射&#xff1b; JPA&#xff08;默认采用Hibernate实现&#xff09;是全自动的ORM框架&#xff0c;提供对象与数据库的映射。 可移植性不同&…...

Linux系统位运算函数以及相应CPU ISA实现收录

以32位数据的二进制表示为例&#xff0c;习惯的写法是LSB在左&#xff0c;MSB在右&#xff0c;注意BIT序和大小端的字节序没有关系。Linux和BIT操作有关的接口在定义在头文件bitops.h中&#xff0c;bitops.h定义有两层&#xff0c;通用层和架构层&#xff0c;对应两个bitops.h&…...

logback配置文件---logback.xml

目录常识操作logback-spring.xml 示例参考于 https://blog.csdn.net/white_ice/article/details/85065219 https://blog.csdn.net/weixin_42592282/article/details/122109703 https://www.dianjilingqu.com/629077.html 常识 https://www.dianjilingqu.com/629077.html nod…...

Web前端-设计网站公共header

设计网站公共headerheader元素是一个具有引导和导航作用的结构元素&#xff0c;很多企业网站中都有一个非常重要的header元素&#xff0c;一般位于网页的开头&#xff0c;用来显示企业名称、企业logo图片、整个网站的导航条&#xff0c;以及Flash形式的广告条等。在本网站中&am…...

引用和指针傻傻分不清

&#x1f680;&#x1f680;&#x1f680;大家觉不错的话&#xff0c;就恳求大家点点关注&#xff0c;点点小爱心&#xff0c;指点指点&#x1f680;&#x1f680;&#x1f680; 目录 &#x1f430;引用和指针的区别 &#x1f338;从现象上看 &#x1f338;从编译上看 &am…...

MySQL面试题:关系型数据库SQL和非关系型数据库NoSQL

文章目录一、四大非关系型数据库与关系型数据库的对比1. 关系型数据库2. 基于列的数据库3. 键值对存储4. 文档存储5. 图形数据库参考文章&#xff08;金文&#xff09;&#xff1a;四大非关系型数据库类型&#xff0c;你知道多少 参考文章&#xff1a;“行式存储”和“列式存储…...

1.Redis【介绍与安装】

1.常用数据库介绍 mysql的表类型[表引擎.存储引擎],memory表结构和表数据分开存储的,表结构保存在硬盘中,表数据保存在内存中memcache是一款软件,可以使用键值对的格式保存数据到内存中redis是意大利的工程师开发的开源免费的告诉缓存数据库,需要注意的是作者本身只开发了linu…...

DataStore快速上手1-preference

DataStore 概念 DataStore 可以存储两种类型的数据&#xff0c;一种是 preference&#xff0c;一种是 protobuf 每个进程在同一时间内仅能打开一个 DataStore 实例&#xff08;或者通过其他管理手段来实现多个 DataStore 交替使用&#xff09; 一个 DataStore 可以视为一张数…...

彻底掌握 MySQL InnoDB 的锁机制

本文是对沈剑大佬锁机制十多篇文章的概括总结&#xff0c;文末有全部链接&#xff0c;还参考了 10 多位其他网友的优秀分享。 1、概要 MySQL 中的锁可以按照粒度分为锁定整个表的表级锁(table-level locking)和锁定数据行的行级锁(row-level locking)&#xff1a; 表级锁具有开…...

C++继承

1.继承的概念及定义 1.1继承的概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层次结构&#x…...

如何对新开网站做收录/seo平台有哪些

步骤1:现成项目步骤2:下载步骤3:导入步骤4:等待步骤5:启动步骤 1 : 现成项目有时候会拿到别人现成的 springboot 项目&#xff0c;而不是从头自己做一个。 这个时候&#xff0c;就需要用导入的方式来 import 这么一个项目了。本教程讲解如何用 eclipse 来导入。步骤 2 : 下载首…...

怎么注销建设银行网站用户名/网络推广工作能长久吗

本文来自&#xff1a;曹胜欢博客专栏。转载请注明出处&#xff1a;http://blog.csdn.net/csh624366188 多线程是java应用程序的一个特点&#xff0c;掌握java的多线程也是作为一java程序员必备的知识。多线程指的是在单个程序中可以同时运行多个同的线程执行不同的任务.线程是程…...

纸业建站服务/上海网络公司seo

1、处理指令 <?xml-stylesheet href"hello.css" type"text/css"?> 在开始标记<?后的第一个字符串“xml-stylesheet”叫做处理指令的目标&#xff0c;它必须标识要用到的应用程序&#xff1b;其余部分是传递应用程序的字符数据。应用程序从处理…...

海外网络推广外包/seo优化易下拉排名

一 创建构建目录结构# mkdir -pv docker/mysql# cd docker/mysql/二 写Dockerfile 文件# vim Dockerfile#此处sshd:latest 为上篇文章中创建的镜FROM sshd:latestMAINTAINER mykernel(www.mykernel.cn)#安装软件RUN ENV DEBIAN_FRONTEND noninteractive apt-get update &…...

自己制作动漫的软件/网站优化助手

敏捷领导力总结一下&#xff1a;您的敏捷转换被困住了。 您已经考虑了自己的原因&#xff0c;就像成为敏捷领导者一样&#xff0c;第1部分&#xff1a;定义原因 。 您已经开始衡量可能性。 您像要成为敏捷领导者&#xff0c;第2部分&#xff1a;与谁接触一样&#xff0c;对与谁…...

网站对品牌的作用/企业文化的重要性

开头 Web前端开发基础知识学习路线分享&#xff0c;前端开发入门学习三大基础&#xff1a;HTML、CSS、JavaScript。除此之外还要学习数据可视化、Vue、React、Angular相关框架&#xff0c;熟练运用框架提升开发效率&#xff0c;提升稳定性。 [外链图片转存失败,源站可能有防盗…...