-
内存、类型本质、连续存储
2018-11-25 19:38:16上图左侧只能存储同一类型的数据连续存储在列表中,既整型和整型,浮点型和浮点型,同类型的存储大小是一样的,因为是连续存储而且存储空间的大小是一样则可以通过索引值获取数据。 右侧则可以通过在列表中存储数据...上图左侧只能存储同一类型的数据连续存储在列表中,既整型和整型,浮点型和浮点型,同类型的存储大小是一样的,因为是连续存储而且存储空间的大小是一样则可以通过索引值获取数据。
右侧则可以通过在列表中存储数据的内存地址来解决存储不同数据类型的问题,因为内存地址的大小是固定的,通过列表的索引值获取到数据的内存地址,然后再通过内存地址获取数据。
左边是一体式,表头和元素地址是连续存储的,可以通过偏移量既索引值直接跳过表头查找元素,直接访问。
右边是分离式,表头和元素的内存地址是分离的,列表先通过表头找到表头的相关信息,然后再通过表头知道元素的内存地址,来间接访问。
建立一个顺序表首先需要向系统申请多大的内存空间(表头),既这个表存储几个元素的最多个数和目前这个表当前的元素个数,,如果你先申请了8个存储元素的空间,实际上你有九个元素需要存储,则会出现有一个元素和另外八个元素不连续存储
所以只能向操作系统重新申请内存空间存储数据,把原表内的数据迁移到新表,且原表的数据内存地址会改变,原表的内存空间会被释放。
如果此时的结构是一体式,则表头的内存地址也要改变。
分离式则只需要把指向数据区的内存地址改变就可以,表头地址不需改变。
-
数据结构之动态数组列表List
2019-12-13 17:06:13数组只能存储同一类型的数据 数组中每个存储空间大小一致且地址连续 数组提供角标的方式访问元素 我们发现数组又有一些局限性,于是在使用时又会有一些疑惑,我们可以总结一下 Java内置数组的潜在...学习了一段时间的Java,我们对Java的基本知识有了一定的了解,今天再来聊聊数组。
Java内置数组的特点
-
数组的长度一旦确定则不可更改
-
数组只能存储同一类型的数据
-
数组中每个存储空间大小一致且地址连续
-
数组提供角标的方式访问元素
我们发现数组又有一些局限性,于是在使用时又会有一些疑惑,我们可以总结一下
Java内置数组的潜在问题容量不够用时,怎么办?
指定位置插入或删除元素,怎么做?
数组对象只有length属性,能满足更多的需求吗?
动态数组的封装
有了问题,我们就有想法,尝试用学过的知识来解决能否用面向对象的思想,将数组进行再度封装呢?
可以的,我们可以把数组的相关属性和相关行为封装在类中
类似字符串String类,形成如下的调用形式
String s="HelloWorld"; s.charAt(1); s.compareTo("Hello"); s.equals("Hello"); s.repalce('l','L');
数组对象.排序()
数组对象.插入(元素)
数组对象.查找(角标)
这样大大方便了我们对数组的操作
那么如何封装动态数组
属性方面:- int size 数组的有效元素个数
- int capacity 数组的最大容量data.length
- E[] data 数据的存储容器
行为方面:
- 增()
- 删()
- 改()
- 查()
- 其他()
为什么要强调动态数组
动态数组是顺序存储结构的具体实现!1)线性表的定义
零个或多个数据元素的有限序列
2)线性表接口List的定义
定义线性表的接口List
List支持泛型E
该List线性表中所存储的具体数据类型由外界决定public interface List<E> extends Iterable<E>{ //获取线性表中元素的有效个数 int getSize(); //判断线性表是否为空表 boolean isEmpty(); //在线性表指定的index角标处插入元素e void add(int index,E e); //在线性表的表头处插入元素e void addFirst(E e); //在线性表的表位处插入元素e void addLast(E e); //获取线性表中指定角标index处的元素 E get(int index); //获取表头元素 E getFirst(); //获取表尾元素 E getLast(); //修改线性表中指定角标index处的元素为新元素e void set(int index,E e); //判断线性表中是否包含元素e boolean contains(E e); //查找元素e的角标(从左到又默认第一个出现的元素角标) int find(E e); //删除并返回线性表中指定角标index处的元素 E remove(int index); //删除并返回表头元素 E removeFirst(); //删除并返回表尾元素 E removeLast(); //删除指定元素e void removeElement(E e); //清空线性表 void clear(); }
创建线性表List的顺序存储结构实现类ArrayList
public class ArrayList<E> implements List<E>{ //创建E类型的一维数组 private E[] data; //维护元素个数 private int size; //默认最大容量为10 private static int DEFAULT_CAPACITY=10; }
先创建一个顺序表 ,重写函数来获取元素有效个数与判断是否为空
//创建一个默认大小的顺序表 public ArrayList(){ this(DEFAULT_CAPACITY); //data=(E[])(new Object[DEFAULT_CAPACITY]); } //创建一个容量由用户指定的顺序表 public ArrayList(int capacity){ if(capacity<=0) { throw new IllegalArgumentException("容量>0:" + capacity); } data=(E[])(new Object[capacity]); size=0; } //用户传入一个数组 将该数组封装成一个顺序表 public ArrayList(E[] data){ if(data==null){ throw new IllegalArgumentException("数组不能为空"); } this.data=(E[])(new Object[data.length]); for (int i = 0; i <data.length ; i++) { this.data[i]=data[i]; } size=data.length; } @Override public int getSize() { return size; } @Override public boolean isEmpty() { return size==0; }
在指定角标插入元素时,如果数组已满,则需要扩容
@Override public void add(int index, E e) { if(index<0||index>size){ throw new IllegalArgumentException("角标越界"); } if(size==data.length){ //扩容 resize(data.length*2); } for (int i = size; i >index ; i--) { data[i]=data[i-1]; } data[index]=e; size++; } private void resize(int newLength) { E[] newData=(E[])(new Object[newLength]); for (int i = 0; i < size; i++) { newData[i]=data[i]; } data=newData; } @Override public void addFirst(E e) { add(0,e); } @Override public void addLast(E e) { add(size,e); }
获取指定元素位置
@Override public E get(int index) { if(isEmpty()){ throw new IllegalArgumentException("线性表为空"); } if(index<0||index>=size){ throw new IllegalArgumentException("角标越界"); } return data[index]; } @Override public E getFirst() { return get(0); } @Override public E getLast() { return get(size-1); }
修改线性表中指定角标index处的元素为新元素e
@Override public void set(int index, E e) { if(isEmpty()){ throw new IllegalArgumentException("线性表为空"); } if(index<0||index>=size){ throw new IllegalArgumentException("角标越界"); } data[index]=e; }
查找元素e的角标(从左到又默认第一个出现的元素角标)
@Override public boolean contains(E e) { return find(e)!=-1; }
在数组中查找是否含有指定元素e
@Override public int find(E e) { if(isEmpty()){ throw new IllegalArgumentException("线性表为空"); } for (int i = 0; i < size; i++) { if(data[i].equals(e)){ return i; } } return -1; }
删除并返回线性表中指定角标index处的元素
@Override public E remove(int index) { if(isEmpty()){ throw new IllegalArgumentException("线性表为空"); } if(index<0||index>=size){ throw new IllegalArgumentException("角标越界"); } E ret=data[index]; for(int i=index+1;i<size;i++){ data[i-1]=data[i]; } size--; if(size<=data.length/4&&data.length/2>=10){ resize(data.length/2); } return ret; } @Override public E removeFirst() { return remove(0); } @Override public E removeLast() { return remove(size-1); }
删除指定元素e
@Override public void removeElement(E e) { int index=find(e); if(index!=-1){ remove(index); }else{ throw new IllegalArgumentException("元素不存在"); } }
清空线性表
@Override public void clear() { size=0; data=(E[])(new Object[DEFAULT_CAPACITY]); }
-
-
数组和列表
2019-09-26 01:15:24Array:数组,申明数组的时候就要初始化并确定长度,长度不可变,而且它只能存储同一类型的数据,比如申明为String类型的数组,那么它只能存储String类型数据 ArrayList:列表,需要先申明,然后再添加数据,长度是...转载于:https://www.cnblogs.com/lph970417/p/10338324.html
-
R语言数据类型
2019-03-13 10:08:00R语言数据类型【转!!... ... R语言用来存储数据的对象包括: 向量, 因子, 数组, 矩阵, 数据框, 时间序列(ts)以及列表, 下面讲意义介绍. ...1. 向量(一维数据): 只能存放同一类型的数据 语法: c(data1, data2,...R语言数据类型【转!!】Zhao-Pace https://www.cnblogs.com/zhao441354231/p/5970544.html
R语言用来存储数据的对象包括: 向量, 因子, 数组, 矩阵, 数据框, 时间序列(ts)以及列表, 下面讲意义介绍.
1. 向量(一维数据): 只能存放同一类型的数据
语法: c(data1, data2, ...), 访问的时候下标从1开始(和Matlab相同); 向量里面只能存放相同类型的数据.
> x <- c(1,5,8,9,1,2,5) > x [1] 1 5 8 9 1 2 5
> y <- c(1,"zhao") # 这里面有integer和字符串, 整数自动转化成了字符
> y[1]
[1] "1"访问:
> x[-(1:2)] # 不显示第1,2个元素 [1] 8 9 1 2 5
> x[2:4] # 访问第2,3,4个元素
[1] 5 8 92. 因子(factors): 提供了一个处理分类数据的更简洁的方式
因子在整个计算过程中不再作为数值, 而是作为一个"符号"而已.
factor(x=character(), levels, labels=levels, exclude=NA, ordered=is.ordered(x), nmax=NA)
x: 一个数据向量, 它将被转换成为因子;
levels: 用来指定因子可能出现的水平(默认也就是向量x里面互异的值, sort(unique(x)));它是一个字符向量(即每个元素是单个字符, 组成的一个向量), 下面的变量b就是一个字符向量(可以使用as.character()函数来生成).
labels: 用来指定水平的名字;
> a <- c(6,1,3,0) > b = as.character(a) > b [1] "6" "1" "3" "0"
exclude: 一个值向量, 表示从向量x里面剔除的水平值.
nmax: 水平数目的上界.
> factor(1:3) [1] 1 2 3 Levels: 1 2 3 > factor(1:3, levels=1:6) [1] 1 2 3 Levels: 1 2 3 4 5 6 > factor(1:6, exclude = 2) [1] 1 <NA> 3 4 5 6 Levels: 1 3 4 5 6
一般因子(factor) VS 有序因子(ordered factor)
因子用来存放变量或者有序变量, 这类变量不能用来计算, 而只能用来分类或者计数. 一般因子表示分类变量, 有序因子用来表示有序变量.
创建一个因子:
> colour <- c('G', 'G', 'R', 'Y', 'G', 'Y', 'Y', 'R', 'Y') > col <- factor(colour) #生成因子 #labels里面的内容代替对应位置处的levels内容 > col1 <- factor(colour, levels = c('G', 'R', 'Y'), labels = c('Green', 'Red', 'Yellow')) > levels(col) [1] "G" "R" "Y" > levels(col1) [1] "Green" "Red" "Yellow" > col2 <- factor(colour, levels = c('G', 'R', 'Y'), labels = c('1', '2', '3')) > levels(col2) [1] "1" "2" "3" > col_vec <- as.vector(col2) > class(col_vec) [1] "character" > col2 [1] 1 1 2 3 1 3 3 2 3 Levels: 1 2 3 > col_num <- as.numeric(col2) > col_num [1] 1 1 2 3 1 3 3 2 3 > col3 <- factor(colour, levels = c('G', 'R')) #levels里面没有'B',导致col3里面的'B'变成了<NA> > col3 [1] G G R <NA> G <NA> <NA> R <NA> Levels: G R > colour [1] "G" "G" "R" "Y" "G" "Y" "Y" "R" "Y"
创建一个有序因子:
> score <- c('A', 'B', 'A', 'C', 'B') > score1 <- ordered(score, levels = c('C', 'B', 'A')); > score1 [1] A B A C B Levels: C < B < A
3. 矩阵(matrix, 二维数据): 只能存放同一类型
语法: matrix(data, nrow = , ncol = , byrow = F) -- byrow = F表示按列来存放数据(默认), byrow=T表示按行存放数据;
> xx = matrix(1:10, 2, 5) > xx [,1] [,2] [,3] [,4] [,5] [1,] 1 3 5 7 9 [2,] 2 4 6 8 10
4. 数组(大于等于三维的数据): 只能存放同一类型
语法: array(data, dim) -- data: 必须是同一类型的数据; dim: 各维的维度组成的向量;(怎么感觉和matlab里面的reshape函数那么像)
> a = array(1:10,c(2,5)) > a [,1] [,2] [,3] [,4] [,5] [1,] 1 3 5 7 9 [2,] 2 4 6 8 10
5. 数据框(data frame)
数据框是一种矩阵形式排列的数据(类似于excel表格), 但是和矩阵不同的是, 它的每一列可以是不同的数据类型(还是和excel很像).
语法: data.frame(data1, data2,...) -- data1,...为每列的数据.
> name <- c("Mr A", "Mr B", "Mr C") > group <- rep(1,3) > scort <- c(58,15,41) > df <- data.frame(name, group, scort) > df name group scort 1 Mr A 1 58 2 Mr B 1 15 3 Mr C 1 41
数据访问:
> df$name [1] Mr A Mr B Mr C Levels: Mr A Mr B Mr C
> df[1]
name
1 Mr A
2 Mr B
3 Mr C6. 列表(list): 可以存放不同类型的数据
语法: list(name1=component1, name2=component2, ...)
> xx <- rep(1:2, 3:4) > yy <- c('Mr A', 'Mr B', 'Mr C', 'Mr D', 'Mr E', 'Mr D', 'Mr F') > zz <- 'discussion group' > name.list <- list(group = xx, name = yy, decription = zz) > name.list $group [1] 1 1 1 2 2 2 2 $name [1] "Mr A" "Mr B" "Mr C" "Mr D" "Mr E" "Mr D" "Mr F" $decription [1] "discussion group"
转载于:https://www.cnblogs.com/wwwwwei/p/10521252.html
-
数据结构与算法---动态数组(1)数组列表ArrayList
2019-12-10 15:51:47数组只能存储同一类型的数据 数组中每个存储空间大小一致且地址连续 数组提供角标的方式访问元素 动态数组的封装 可以把数组的 相关属性和相关行为封装在类中 线性表的顺序存储结构 线性表的定义:零个或多个... -
python基础系列(三)之高级数据结构
2016-10-01 16:21:06引言:在python中,诸如列表list,字典dict,集合set,元组tuple的用法十分灵活。特别是区别于传统的数组的概念。传统的数组一般只能存储同一类型的数据,而python中的数据结构更像是一个可以容纳任意类型数据的容器。 -
数组(Array)和列表(ArrayList)有什么区别?什么时候应该使用Array而不是ArrayList?
2017-11-09 08:53:31Array:它是数组,申明数组的时候就要初始化并确定长度,长度不可变,而且它只能存储同一类型的数据,比如申明为String类型的数组,那么它只能存储S听类型数据 ArrayList:它是一个集合,需要先申明,然后再添加... -
共用体处理任意类型数据
2018-06-01 19:50:37共用体是一种数据格式,它能够存储不同的数据类型,但在同一时间只能存储其中的一种类型。共用体的用途之一是,当数据使用两种或更多种格式,但不会同时使用这些格式时,可以节省空间。 union 共用体名 { 成员... -
Python基础—数据类型集合
2019-08-31 19:18:59同一集合中,只能存储不可变的数据类型,包括整形、浮点型、字符串、元组,无法存储列表、字典、集合可变的数据类型 集合的分类 1. 可变集合(set):可以进行增删改操作 s1 = {1, 2, 3, 4} print(s1, type(s1)) # {... -
java之数组与列表
2020-05-22 19:38:19在数组中只能存储同一类型的数据,在定义数组的时候必须要指定数据类型。数组能存储的元素个数是固定的,因为数组在定义的时候必须要指定长度。 Java中数组是类,它只有唯一一个属性 length。length属性表示的是... -
python之列表、元组、字典
2018-01-04 19:17:50打了激素的数组数组是只能存储同一数据类型的结构列表:可以存储多数数据类型的数组 2 定义列表: 元组和列表的不同:元组是不可变对象而列表是可变对象 3 列表的特性: 1 索引 分为前向索引、反向索引和多重... -
python 数组VS列表
2020-05-20 15:42:34最近的两次面试里都有这个基础问题,实在不明白“标准答案”应该是啥。... 2)numpy中ndarray对象用于处理多维数组,只能存储同一类型,其效率存储,输入输出效率都高于python列表嵌套实现的多维数组。ndarray... -
JAVA技术方向面试题-核心类库(上)
2021-02-27 20:31:51文章目录一、数组(Array)和...Array:它是数组,申明数组的时候就要初始化并确定长度,长度不可变,而且它只能存储同一类型的数据,比如申明为String类型的数组,那么它只能存储String类型数据 ArrayList:它是一个集 -
python中的数组和列表
2020-08-29 23:34:33Python 的 array 是内存连续、存储的都是同一数据类型的结构,而且只能存数值和字符。 可以看下 array 的文档:https://docs.python.org/2/library/array.html 简单使用示例: from array import array # python ... -
集合小节 ==与equals的区别
2011-03-12 19:37:24集合是用来存储同一类型的数据,和数组很像.但数组的长度是不能自动增长的,且只能存放相同类型的元素,而集合可以自动增长,部分集合还可以允许存放不同类型的元素,但集合中不能存放基本数据类型。java中集合主要... -
Python 集合数据类型之一: set [学习 Python 必备基础知识][看此一篇就够了][创建set集合][访问set集合]...
2020-05-11 21:42:14Python 中的 `set` 集合,将所有元素放在一对大...在同一集合中,只能存储不可变的数据类型,包括数字、字符串、元组;无法存储列表、set 集合、字典这些可变的数据类型,否则 Python 解释器会抛出 `TypeError` 错误。 -
leetcode-python刷题 2.1 两数相加
2020-10-12 20:50:31在很多语言中,数组的大小要提前定义,定义后不能随便更改,而且数组中只能存储同一类型的变量。使用链表,可以改变数组的长度,并且可以在同一数组中存储不同类型的元素,和 python 中的列表很像,事实上列表的工作... -
.dat文件写入byte类型数组_C语言学习之联合类型
2020-11-24 13:27:27前言联合(union)是一种特殊的数据类型,和结构体很像,结构体各成员变量有自己独立的存储位置,而联合的成员变量共享同一片存储区域,因此联合变量再一个时刻只能保存它的某一个成员的值。联合的定义和初始化联合的... -
Java里的集合--主要区别
2019-10-04 01:26:49Collection 集合接口,指的是 java.util.Collection接口,是 Set、List 和 Queue 接口的超类接口。... List用来存放同一类型的数据,只能一个一个存放,不能存放键值对。 List是有顺序的存储。 List主... -
python——数组和列表
2020-06-10 16:04:55线性结构 本节我们从最简单和常用的线性结构开始,并结合 Python 语言本身内置的数据结构和其底层实现... Python 的 array 是内存连续、存储的都是同一数据类型的结构,而且只能存数值和字符。 我建议你课下看下 arra -
C语言学习之联合类型
2019-02-27 13:02:00联合(union)是一种特殊的数据类型,和结构体很像,结构体各成员变量有自己独立的存储位置,而联合的成员变量共享同一片存储区域,因此联合变量再一个时刻只能保存它的某一个成员的值。 联合的定义和初始化 联合的... -
python内置对象类型(五)序列之set集合
2020-10-31 22:37:09{} 中相邻元素之间用“,”分隔,从内容上看,同一集合中,只能存储不可变的数据类型,包括整形、浮点型、布尔型、字符串、元组,无法存储列表、字典、集合这些可变的数据类型,否则 Python 解释器会抛出 TypeError ... -
数据结构(python)
2019-07-09 14:38:00列表 list 在头部进行插入是个相当耗时的操作(需要把后边的元素一个一... Python 的 array 是内存连续、存储的都是同一数据类型的结构,而且只能存数值和字符。 最常用的还是 list 来实现一个固定长度、并且支持... -
【java】Collection框架
2015-03-20 17:05:45数组长度是固定的,集合长度是可变的数组中只能存储同一类型的对象,而集合中存储的只要是对象就行★集合框架:是不断向上抽取共性出来的 Collection框架中包含了大量集合接口以及这些接口的实现类和操作它们的算法... -
JavaScript中数组的概念
2020-10-28 21:11:05之前学习的数据类型,只能存储一个值(比如:Number/String。我们想存储班级中所有学生的姓名,此时该如何存储? 数组的概念 所谓数组,就是将多个元素(通常是同一类型)按一定顺序排列放到一个集合中。那么这个集合... -
集合&迭代器
2019-11-14 20:49:20集合(collection)概述: 长度是可以随意改变的 ...数组:1、存储多个同一种类型的数据(基本数据类型、引用数据类型的对象) 2、长度是固定的 3、有默认值 定义方式: 1、动态声明int[] arr=new int[]; 2、静态声... -
Python学习中的一些注意事项总结(2)
2020-01-17 17:31:04(3)同一集合中,只能存储不可变的数据类型,包括整形、浮点型、字符串、元组,无法存储列表、字典、集合这些可变的数据类型,否则 Python 解释器会抛出 TypeError 错误。 (4)由于 Python 中...