数据结构之第四章、ArrayList和顺序表
一、线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
二、顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
2.1接口的实现
public class SeqList {private int[] array;private int size;private static final DEFAULT_CAPACITY;// 将顺序表的底层容量设置为DEFAULT_CAPACITYSeqList(){ }//判断是否达到容量public boolean isFull();//扩容机制public void resize();// 新增元素,默认在数组最后新增public void add(int data) { }// 在 pos 位置新增元素public void add(int pos, int data) { }// 判定是否包含某个元素public boolean contains(int toFind) { return true; }// 查找某个元素对应的位置public int indexOf(int toFind) { return -1; }// 获取 pos 位置的元素public int get(int pos) { return -1; }// 给 pos 位置的元素设为 valuepublic void set(int pos, int value) { }//判断顺序表是否为空public boolean isEmpty();//删除第一次出现的关键字keypublic void remove(int toRemove) { }// 获取顺序表长度public int size() { return 0; }// 清空顺序表public void clear() { }// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display() { }
}
//---------------------------------------------------------------------------------------//自定义异常public class PosOutOfException extends RuntimeException;
2.2方法的实现
public class SeqList {//定义数组private int[] array;//有效数据private int usedsize;private static final int DEFAULT_CAPACITY=5;// 默认构造方法// 将顺序表的底层容量设置为DEFAULT_CAPACITYSeqList(){this.array=new int[DEFAULT_CAPACITY];}// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display() {for (int i = 0; i < usedsize; i++) {System.out.print(array[i]);}System.out.println();}//判断是否达到容量public boolean isFull(){if(usedsize==DEFAULT_CAPACITY){return false;}return true;}//扩容机制public void resize(){array=Arrays.copyOf(array,2* array.length);}// 新增元素,默认在数组最后新增public void add(int data) {if(isFull()){resize();}this.array[usedsize]=data;usedsize++;}// 在 pos 位置新增元素public void add(int pos, int data) {if(!Pos(pos)){throw new posOutOfException();}if(isFull()){resize();}//挪动数据for (int i = this.usedsize-1; i >=pos; i--) {this.array[i+1]=this.array[i];}this.array[pos]=data;this.usedsize++;}// 判定是否包含某个元素public boolean contains(int toFind) {for (int i = 0; i < this.usedsize; i++) {if(this.array[i]==toFind){return true;}}return false;}// 查找某个元素对应的位置public int indexOf(int toFind) {for (int i = 0; i < this.usedsize; i++) {if(this.array[i]==toFind){return i;}}return -1;}//判断pos位置元素是否符合要求public boolean Pos(int pos){if(pos>=this.usedsize||pos<0){return false;}return true;}// 获取 pos 位置的元素public int get(int pos) {if(Pos(pos)==true){return array[pos];}throw new posOutOfException();}// 给 pos 位置的元素设为 valuepublic void set(int pos, int value) {if(!Pos(pos)){throw new posOutOfException("set数据时,位置不合法!");}this.array[pos]=value;}//删除第一次出现的关键字keypublic void remove(int toRemove) {if(isEmpty()){return ;}int index=indexOf(toRemove);if(indexOf(toRemove)==-1){return ;}else{for (int i = index; i < this.usedsize-1; i++) {this.array[i] = this.array[i+1];}}this.usedsize--;}//判断顺序表是否为空public boolean isEmpty(){return this.usedsize==0;}// 获取顺序表长度public int size() {return this.usedsize;}// 清空顺序表public void clear() {for (int i = 0; i < this.usedsize; i++) {array[i]=0;}//引用类型:array[i]=null;this.usedsize=0;}
}
三、ArrayList简介
在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
【说明】
- ArrayList是以泛型方式实现的,使用时必须要先实例化
- ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
- ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
- ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
- 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
- ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
四、ArrayList使用
4.1ArrayList的构造
4.1.1ArrayList的无参构造
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);}
查看底层源码看ArrayList的底层代码实现:
再看add方法:
综上分析:
- 当调用不带参数的构造方法的时候,默认数组长度为0。
- 当第一次add的时候,才会分配内存,且分配内存的容量为10。
4.1.2指定顺序表初始容量的构造方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>(10);list.add(10);}
查看相应源码:
4.1.3借助Collection构造
class People{}
class Student extends People{}
class Animal{}
public class Demo1 {public static void main(String[] args) {ArrayList<Student> list=new ArrayList<>();ArrayList<People> list2=new ArrayList<>(list);//list是People的子类ArrayList<Animal> list3=new ArrayList<>();ArrayList<People> list4=new ArrayList<>(list3);}
}
构造方法小结:
public static void main(String[] args) {// ArrayList创建,推荐写法// 构造一个空的列表List<Integer> list1 = new ArrayList<>();// 构造一个具有10个容量的列表List<Integer> list2 = new ArrayList<>(10);list2.add(1);list2.add(2);list2.add(3);// list2.add("hello"); // 编译失败,List<Integer>已经限定了,list2中只能存储整形元素// list3构造好之后,与list中的元素一致ArrayList<Integer> list3 = new ArrayList<>(list2);// 避免省略类型,否则:任意类型的元素都可以存放,使用时将是一场灾难List list4 = new ArrayList();list4.add("111");list4.add(100);}
4.2ArrayList常见操作
常见方法如下:
4.2.1 add(E e)方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);ArrayList<String> list2=new ArrayList<>();list2.add("Hello ");list2.add("World!");}
4.2.2 add(int index,E element)方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);ArrayList<String> list2=new ArrayList<>();list2.add("Hello ");list2.add("World!");list2.add(0,"Java:");System.out.println("=========");}
4.2.3 addAll(Collection<? extends E> c)方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);ArrayList<String> list2=new ArrayList<>();list2.add("Hello ");list2.add("World!");list2.add(0,"Java:");ArrayList<String> list3=new ArrayList<>();list3.addAll(list2);System.out.println("=========");}
4.2.4 remove(int index)方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);ArrayList<String> list2=new ArrayList<>();list2.add("Hello ");list2.add("World!");list2.add(0,"Java:");list.remove(2);list2.remove(0);System.out.println("========");}
4.2.5 get(int index)方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);ArrayList<String> list2=new ArrayList<>();list2.add("Hello ");list2.add("World!");list2.add(0,"Java:");System.out.println(list.get(1));System.out.println(list2.get(0));//20//Java:System.out.println("========");}
4.2.6 set(int index,E element)方法
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);ArrayList<String> list2=new ArrayList<>();list2.add("Hello ");list2.add("World!");list2.add(0,"Java:");list.set(1,30);list2.set(0," ");System.out.println("========");}
4.2.7 List<E> subList(int fromIndex, int toIndex)方法注意事项
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);List<Integer> list2=list.subList(0,2);list2.set(0,100);System.out.println("========");}
这里的截取并不是返回一个新的顺序表,而是指向截取的范围的引用。此时发生的并不是一个拷贝。功能总结练习:
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("JavaSE");list.add("JavaWeb");list.add("JavaEE");list.add("JVM");list.add("测试课程");System.out.println(list);
// 获取list中有效元素个数System.out.println(list.size());
// 获取和设置index位置上的元素,注意index必须介于[0, size)间System.out.println(list.get(1));list.set(1, "JavaWEB");System.out.println(list.get(1));
// 在list的index位置插入指定元素,index及后续的元素统一往后搬移一个位置list.add(1, "Java数据结构");System.out.println(list);
// 删除指定元素,找到了就删除,该元素之后的元素统一往前搬移一个位置list.remove("JVM");System.out.println(list);
// 删除list中index位置上的元素,注意index不要超过list中有效元素个数,否则会抛出下标越界异常list.remove(list.size()-1);System.out.println(list);
// 检测list中是否包含指定元素,包含返回true,否则返回falseif(list.contains("测试课程")){list.add("测试课程");} // 查找指定元素第一次出现的位置:indexOf从前往后找,lastIndexOf从后往前找list.add("JavaSE");System.out.println(list.indexOf("JavaSE"));System.out.println(list.lastIndexOf("JavaSE"));
// 使用list中[0, 4)之间的元素构成一个新的SubList返回,但是和ArrayList共用一个elementData数组List<String> ret = list.subList(0, 4);System.out.println(ret);list.clear();System.out.println(list.size());}
4.2.8ArrayList的输出方式
通过ARrayList源码逐步查看:
4.3ArrayList的遍历操作
ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器
4.3.1通过for循环遍历
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);System.out.println("========");for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}//10//20//150}
4.3.2通过for-each遍历
左边:右边:---->
右边是要进行遍历的集合
左边是集合当中元素的类型所定义的变量
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);System.out.println("========");for (Integer i:list) {System.out.println(i);}//10//20//150}
4.3.3通过迭代器遍历
public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(150);list.add(1,20);System.out.println("========");Iterator<Integer> it=list.iterator();//it相当于指针,走一步输出一个走一步输出一个//这就是迭代器while(it.hasNext()){//如果有下一个就输出下一个System.out.println(it.next());}//10//20//150}
注意:
1. ArrayList最常使用的遍历方式是:for循环+下标 以及 foreach
2. 迭代器是设计模式的一种,后序容器接触多了再给大家铺垫3.
4.4ArrayList的扩容机制
ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。以下是ArrayList源码中扩容方式:
Object[] elementData; // 存放元素的空间private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空间private static final int DEFAULT_CAPACITY = 10; // 默认容量大小public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);} return minCapacity;}private void ensureExplicitCapacity(int minCapacity) {modCount++;
// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;private void grow(int minCapacity) {
// 获取旧空间大小int oldCapacity = elementData.length;
// 预计按照1.5倍方式扩容int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容if (newCapacity - minCapacity < 0)newCapacity = minCapacity;
// 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);
// 调用copyOf扩容elementData = Arrays.copyOf(elementData, newCapacity);}private static int hugeCapacity(int minCapacity) {
// 如果minCapacity小于0,抛出OutOfMemoryError异常if (minCapacity < 0)throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;}
【总结】
1. 检测是否真正需要扩容,如果是调用grow准备扩容
2. 预估需要库容的大小,初步预估按照1.5倍大小扩容。如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容,真正扩容之前检测是否能扩容成功,防止太大导致扩容失败。
3. 使用copyOf进行扩容
五、ArrayList的具体使用
5.1实现洗牌算法
public class Card {//创建牌private int rank;//牌面值private String suit;//花色//构造方法+set和getpublic Card() {}public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}public int getRank() {return rank;}public void setRank(int rank) {this.rank = rank;}public String getSuit() {return suit;}public void setSuit(String suit) {this.suit = suit;}//重写toString方法public String toString(){return suit+" "+rank;}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Cards {//四种花色的字符串数组private static final String[] SUITS={"♥","♠","♣","♦"};public static List<Card> buyCard(){//创建52张牌,每个花色13张牌List<Card> list=new ArrayList<>();for (int i=0;i<SUITS.length;i++){for (int j = 1; j <=13 ; j++) {Card card=new Card(j,SUITS[i]);list.add(card);}}return list;}//实现牌组的交换public static void shuffle(List<Card> list){Random output=new Random();for (int i = list.size()-1; i >0 ; i--) {int j=output.nextInt(i);//实现牌组的交换Card tmp=list.get(i);list.set(i,list.get(j));list.set(j,tmp);}}public static void main(String[] args) {//置牌List<Card> list=buyCard();System.out.println(list);System.out.println("洗牌:");shuffle(list);System.out.println(list);System.out.println("发牌:");List<Card> list1=new ArrayList<Card>();List<Card> list2=new ArrayList<>();List<Card> list3=new ArrayList<>();//ArrayList构造方法List<List<Card>> hand=new ArrayList<>();hand.add(list1);hand.add(list2);hand.add(list3);for (int i = 0; i < 14; i++) {for (int j = 0; j < hand.size(); j++) {//摸牌动作Card tmp=list.remove(0);hand.get(j).add(tmp);}}System.out.println("第一个人的牌数:");System.out.println(list1);System.out.println("第二个人的牌数:");System.out.println(list2);System.out.println("第三个人的牌数:");System.out.println(list3);}
}
六、ArrayList的问题及思考
6.1顺序表的优点
- 根据指定下标(索引)去查找元素,效率非常高!时间复杂度为O(1)。
- 更新元素也很快:更新指定下标的元素。时间复杂度为O(1)。
6.2顺序表的缺点
- 每次插入数据,都需要移动元素。极端情况下,如果插入到0下标,那么移动的元素复杂度O(N)。
- 每次删除数据的时候,都需要移动元素。极端情况下,删除0下标的元素的时间复杂度为O(N)。
- 当容量满后进行1.5倍扩容。然后只放了一个元素,此时可能会浪费空间。
6.3总结
顺序表适用于经常进行查找元素或者更新元素的场景下,此时推荐使用顺序表。
相关文章:

数据结构之第四章、ArrayList和顺序表
一、线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列... 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是…...

webase全家桶搭建教程过程记录+bug解决
前置条件 Ubuntu20 基础环境搭建 检查Java java -version 检查mysql(Ubuntu部署MySQL) mysql --version 在装MySQL的时候发现了一个问题 就是不管怎么sudo mysql_secure_installation,,第二步设置密码就是不对,解…...

openEuler Linux 部署 HadoopHA
openEuler Linux 部署 HadoopHA 升级操作系统和软件 yum -y update升级后建议重启 安装常用软件 yum -y install gcc gcc-c autoconf automake cmake make rsync vim man zip unzip net-tools zlib zlib-devel openssl openssl-devel pcre-devel tcpdump lrzsz tar wget修改…...

React-Hooks----useEffect()
文章目录前言用法前言 useEffect() 是 React 中最常用的 Hook 之一,它可以让函数组件拥有类似于类组件中 componentDidMount、componentDidUpdate 和 componentWillUnmount 生命周期函数的功能。 用法 useEffect() 接受两个参数 第一个参数是一个函数,…...

JavaWeb基础-汇总
SSM框架课程汇总01-MySQL基础02-MySQL高级03-JDBC04-JDBC练习05-Maven&Mybatis基础06-Mybatis练习07-JavaScript08-Web概述09-HTTP10-Tomcat11-Servlet12-Request&Response13-用户注册登录案例14-JSP15-JSP案例16-会话技术17-用户登录注册案例18-Filter19-Listener&…...

Niuke:JZ36.二叉树与双向链表
文章目录Niuke:JZ36.二叉树与双向链表题目描述示例思路分析代码实现Niuke:JZ36.二叉树与双向链表 题目描述 描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示 注意: 1.要求不能创建任何新的结点,只…...

javaScript---读懂promise、async/await
一、Promise Promise 是一个 Es 6 提供的类,目的是更加优雅地书写复杂的异步任务。可以解决嵌套式的回调地域问题,Promise 将嵌套格式的代码变成了顺序格式的代码。 //回调地域 setTimeout(function () {console.log("红灯");setTimeout(function () {console.lo…...

【Linux】TCP编程流程
TCP编程流程 socket()创建套接字,套接字TCP协议选择流式服务SOCK_STREAM。 bind()指定套接字使用的IP地址和端口。IP地址是自己主机地址,端口为一个16位的整形值。 listen()方法创建监听队列。监听队列分为存放未完成三次握手的连接和完成三次握手的连…...

SuperMap iDesktop 下载安装,生成本地瓦片,以及发布本地瓦片服务
SuperMap iDesktop 是插件式桌面GIS软件,提供基础版、标准版、专业版和高级版四个版本,具备二三维一体化的数据处理、制图、分析、海图、二三维标绘等功能,支持对在线地图服务的无缝访问及云端资源的协同共享,可用于空间数据的生产…...

【ONE·Data || 常见排序说明】
总言 数据结构基础:排序相关内容。 文章目录总言1、基本介绍2、插入排序2.1、直接插入排序:InsertSort2.1.1、单趟2.1.2、总趟2.2、希尔排序(缩小增量排序):ShellSort2.2.1、预排序1.0:单组分别排序2.…...

本节作业之跟随鼠标的天使、模拟京东按键输入内容、模拟京东快递单号查询
本节作业之跟随鼠标的天使、模拟京东按键输入内容、模拟京东快递单号查询1 跟随鼠标的天使2 模拟京东按键输入内容3 模拟京东快递单号查询1 跟随鼠标的天使 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><met…...

ChatGPT 被大面积封号,到底发生什么了?
意大利数据保护机表示 OpenAI 公司不但非法收集大量意大利用户个人数据,没有设立检查 ChatGPT 用户年龄的机制。 ChatGPT 似乎正在遭遇一场滑铁卢。 3月31日, 大量用户在社交平台吐槽,自己花钱开通的 ChatGPT 账户已经无法登录,更…...

教你精通JavaSE语法之第十一章、认识异常
一、异常的概念与体系结构 1.1异常的概念 在Java中,将程序执行过程中发生的不正常行为称为异常。比如之前写代码时经常遇到的: 1.算术异常 System.out.println(10 / 0); // 执行结果 Exception in thread "main" java.lang.ArithmeticExcep…...

display、visibility、opacity隐藏元素的区别
display、visibility、opacity隐藏元素的区别 display: none 事件监听:无法进行DOM事件监听。 元素从网页中消失,并且不占据位置再次从网页中出现会引起重排 进而引起重绘继承:不会被子元素继承,因为子元素也不被渲染。 visib…...

Linux Shell 实现一键部署tomcat10+java13
tomcat 前言 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当…...

软硬皆施,WMS仓库管理系统+PDA,实现效率狂飙
人工经验Excel表格,是传统第三方仓储企业常用的管理模式。在这种管理模式下,对仓库员工的Excel操作能力、业务经验和工作素养要求极高。一旦员工的经验能力不足,就会导致仓库业务运行不顺畅,效率低下,而员工也会因长时…...

DJ3-2 传输层(第二节课)
目录 一、如何实现可靠数据传输 1. 需要解决地问题 2. 使用的描述方法 二、rdt1.0:完全可靠信道上的可靠数据传输 1. 前提条件 2. 有限状态机 FSM 三、rdt2.0:仅具有 bit 错误的信道上的可靠数据传输 1. 前提条件 2. 有限状态机 FSM 3. 停等协…...

FrIf-FrIf功能模块概述和与底层驱动的交互
总目录链接==>> AutoSAR入门和实战系列总目录 总目录链接==>> AutoSAR BSW高阶配置系列总目录 文章目录 1 FlexRay 接口模块概述2 与FlexRay底层驱动的交互1 FlexRay 接口模块概述 FlexRay 接口模块通过 FlexRay 驱动程序模块间接与 FlexRay 控制器通信。 它…...

【LeetCode】前 K 个高频元素(堆)
目录 1.题目要求: 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 2.解题思路: 代码展示: 1.题目要求: 给你一个整数数组 nums 和一个整数 k ࿰…...

Java ---多态
(一)定义 官方:多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。 生活中的多态,如图所示: 多态性是对象多种表现形式的体现。 现实中,…...

13个程序员常用开发工具用途推荐整理
作为一名刚入门的程序员,选择合适的开发工具可以提高工作效率,加快学习进度。在本文中,我将向您推荐10个常用的开发工具,并通过简单的例子和代码来介绍它们的主要用途。 1. Visual Studio Code Visual Studio Code(V…...

TCP分包和粘包
文章目录TCP分包和粘包TCP分包TCP 粘包分包和粘包解决方案:TCP分包和粘包 TCP分包 场景:发送方发送字符串”helloworld”,接收方却分别接收到了两个数据包:字符串”hello”和”world”发送端发送了数量较多的数据,接…...

手撕深度学习中的优化器
深度学习中的优化算法采用的原理是梯度下降法,选取适当的初值params,不断迭代,进行目标函数的极小化,直到收敛。由于负梯度方向时使函数值下降最快的方向,在迭代的每一步,以负梯度方向更新params的值&#…...

英文打字小游戏
目录 1 实验目的 2 实验报告内容 3 实验题目 4 实验环境 5 实验分析和设计思路 6 流程分析和类图结构 编辑 7. 实验结果与测试分析 8. 总结 这周没有更新任何的文章,感到十分的抱歉。因为我们老师让我们做一个英文打字的小游戏,并要求撰写实验…...

PCB生产工艺流程三:生产PCB的内层线路有哪7步
PCB生产工艺流程三:生产PCB的内层线路有哪7步 在我们的PCB生产工艺流程的第一步就是内层线路,那么它的流程又有哪些步骤呢?接下来我们就以内层线路的流程为主题,进行详细的分析。 由半固化片和铜箔压合而成,用于…...

算法竞赛进阶指南0x61 最短路
对于一张有向图,我们一般有邻接矩阵和邻接表两种存储方式。对于无向图,可以把无向边看作两条方向相反的有向边,从而采用与有向图一样的存储方式。 $$ 邻接矩阵的空间复杂度为 O(n^2),因此我们一般不采用这种方式 $$ 我们用数组模…...

[学习篇] Autoreleasepool
参考文章: https://www.jianshu.com/p/ec2c854b2efd https://suhou.github.io/2018/01/21/%E5%B8%A6%E7%9D%80%E9%97%AE%E9%A2%98%E7%9C%8B%E6%BA%90%E7%A0%81----%E5%AD%90%E7%BA%BF%E7%A8%8BAutoRelease%E5%AF%B9%E8%B1%A1%E4%BD%95%E6%97%B6%E9%87%8A%E6%94%BE/ …...

晶体基本知识
文章目录晶体基本知识基本概念晶胞<晶格<晶粒<晶体晶胞原子坐标(原子分数坐标)六方晶系与四轴定向七大晶系和十四种点阵结构学习资料吉林大学某实验室教程---知乎系列晶体与压敏器件晶体基本知识 基本概念 晶胞<晶格<…...

免费CRM如何进行选择?
如今CRM领域成为炙手可热的赛道,很多CRM系统厂商甚至打出完全免费的口号,是否真的存在完全免费的crm系统?很多企业在免费使用过程中会出现被迫终止的问题,需要花费高价钱才能继续使用,那么,免费crm系统哪个…...

关于金融类iOS套壳上架,我帮你总结了这些经验
首先说明,本文中出现的案例的,没有特别的专门针对谁,只是用于分析,如有觉得不妥的,请及时联系我删除,鉴于本文发出之后,可能造成的一些影响,所以大家看看就好了,千万不要…...