<数据结构基础学习>(一)数组
一.数组基础
1.数组,即把数据码成一排存放。
数组优点:快速查询。
数组最好应用于“索引有语意”的情况,但并非所有有语意的索引都适用于数组,数组也可以处理“索引没有语意”的情况。
2.增、删、改、查,是研究数据结构的基本脉络。
设二次封装的数组的类Array<E>(类型为E,泛型),E[ ] data 基本参数有capacity和size。
capacity为数组空间最多装的元素个数,即data.length。
size为数组实际装的元素个数。
有些方法需要对size进行维护。
二. 动态数组常见方法
1.基础方法
1)方法1:有参构造函数设置动态数组的capacity
java不支持data = new E[capacity],需写为data=(E[])new Object[capacity]
2)方法2:无参构造函数默认数组的capacity为10
3)方法3:获取数组元素个数 即size
4)方法4:获取数组的容量 即capacity,data.length
5)方法5:返回数组是否为空 即判断size是否为0
public class Array<E> {
private E[] data;
private int size; //构造函数,传入数组的容量capacity构造Array
public Array(int capacity){
data = (E[]) new Object[capacity];
size = 0;
} //无参数的构造函数,默认的数组容量capacity=10
public Array(){
this(10);
} //获取数组中的元素个数
public int getSize(){
return size;
} //获取数组的容量
public int getCapacity(){
return data.length;
} //返回数组是否为空
public boolean isEmpty(){
return size == 0;
}
}
2.增(插入元素)
1)方法1:在index位置插入元素
add(int index, E e)
a.先判断index是否合法,若index<0||index>size,则抛出异常
b.若index == data.length,此时需要调用resize()方法对数组进行扩容(扩容为2*capacity)
private void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity];
for(int i = 0 ; i < size ; i ++){
newData[i] = data[i];
}
data = newData;
}
resize()方法思想即创建一个容量为newCapacity的新数组newData,通过将data中的每个元素依次赋值给newData,最后令data=newData。
c.在指定位置插入元素的思想,即为从最后一位(size-1)开始,开始循环将元素向后挪一位(data[i+1]=data[i]),直到index的位置。
然后令data[index]=e,
最后,维护size,即size++
2)方法2:向所有元素后添加元素
addLast(E e) 即add(size, e)
3)方法3:向首位值添加元素
addFirst(E e) 即add(0, e)
//向所有元素后添加元素
public void addLast(E e){
add(size, e);
}
//向首位指添加元素
public void addFirst(E e){
add(0,e);
} // important index位置插入元素e
public void add(int index, E e){ if( index < 0 || index > size){
throw new IllegalArgumentException("AddLast failed. Require index < 0 || index > size");
} if(size == data.length){
resize(2 * data.length);
} for(int i = size - 1 ; i >= index ; i -- ){
data[ i + 1 ] = data[i];
} data[index] = e;
size ++;
}
3.查(查询元素)
1)方法1:获取index索引位置的元素
get(int index)
a.先判断index是否合法,若index<0||index>=size,则抛出异常
b.返回data[index]
2)方法2:查找数组中是否有元素e
contains(E e)
循环查找,若有data[i].equals(e),则返回true,否则返回false。(java中判断类对象的值是否相等采用.equals()方法)
3)方法3:查找元素e所在的索引index,若元素不存在,则返回-1
find(E e)
循环查找,若有data[i].equals(e),则返回i,否则返回-1
//获取index索引位置的元素
E get(int index){
if(index < 0 || index >= size){
throw new IllegalArgumentException("Get failed. Index is illegal");
}
return data[index];
}
//查找数组中是否有元素e
public boolean contains(E e){
for(int i = 0 ; i < size; i ++){
if(data[i].equals(e))
return true;
}
return false;
} //查找数组中元素e所在的索引,如果不存在元素e,则返回-1
public int find(E e){
for(int i = 0 ; i < size ; i ++){
if(data[i].equals(e)){
return i;
}
}
return -1;
}
4.删(删除元素)
1)方法1:从数组中删除index位置的元素,并返回删除的元素
remove(int index)
a.先判断index是否合法,若index<0||index>=size,则抛出异常。
b.定义ret=data[index],作为返回值。
c.开始删除操作,即从i=index位置开始,循环地使data[i]=data[i+1],即将下一位元素覆盖到当前元素中,直到size-1。
d.维护size,即 size --。
e.(非必需)但此时data[size]还是存在用不到的数的,可以进行data[size]=null的操作来避免空间浪费。
f.判断当前size==data.length/2,如果为true,则进行缩容,调用resize()方法,使capacity=data.length/2,避免空间浪费。
g.返回ret,即删除的元素。
2)方法2:删除首个位置的元素并返回该元素
remove(0)
3)方法3:删除末尾位置的元素并返回该元素
remove(size)
4)方法4:直接从数组中删除元素e
emoveElement(E e)方法
先通过find()方法寻找e的index,若存在则返回e的index,不存在则返回-1,当index不为-1时,remove(index)
//从数组中删除index位置的元素,并返回删除的元素
public E remove(int index){
if( index < 0 || index >= size)
throw new IllegalArgumentException("Remove failed. Index is illegal"); E ret = data[index]; for(int i = index ; i < size - 1 ; i ++){
data[i] = data[i + 1];
}
size --;
data[size] = null; //loitering objects != memory leak is Better if(size == data.length/2 )
resize(data.length/2);
return ret;
} //删除首个位置的元素
public E removeFirst(){
return remove(0);
} //删除最后一个元素
public E removeLast(){
return remove(size - 1);
} //从数组中删除元素e
public void removeElement(E e){
int index = find(e);
if(index != -1)
remove(index);
}
5.改(重置数组中的元素)
set(int index, E e)
a.先判断index是否合法,若index<0||index>=size,则抛出异常。
b.令data[index] = e
//修改index索引位置的元素e
void set(int index, E e){
if(index < 0 || index >=size){
throw new IllegalArgumentException("Set failed. Index is illegal");
} data[index] = e;
}
6.重写toString()方法,让输出更具有可读性
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length));
res.append('[');
for(int i = 0 ; i < size ; i ++){
res.append(data[i]);
if(i != size-1){
res.append(", ");
}
}
res.append(']');
return res.toString();
}
<数据结构基础学习>(一)数组的更多相关文章
- Java基础学习之数组基本属性和方法
数组对于每一门编程语言都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同.Java语言中提供的数组是用来存储固定大小的同类型元素.你可以声明一个数组变量,如 int[100] 来代替直接 ...
- <数据结构基础学习>(四)链表 Part 1
一.链表基础 动态数组.栈.队列底层都是依托静态数组实现的,靠resize来解决固定容量问题. 链表是真正的动态数据结构,是一种最简单的一种动态数据结构. 更深入的理解引用(或者指针). 更深入的理解 ...
- <数据结构基础学习>(三)Part 1 栈
一.栈 Stack 栈也是一种线性的数据结构 相比数组,栈相对应的操作是数组的子集. 只能从一端添加元素,也只能从一端取出元素.这一端成为栈顶. 1,2,3依次入栈得到的顺序为 3,2,1,栈顶为3, ...
- <数据结构基础学习>(三)Part 2 队列
一.队列 Queue 队列也是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另一端(队首)取出元素. (排队) 队列是一种先进先出的数据结构(先到先得)FIFO ...
- C语言数据结构基础学习笔记——树
树是一种一对多的逻辑结构,树的子树之间没有关系. 度:结点拥有的子树数量. 树的度:树中所有结点的度的最大值. 结点的深度:从根开始,自顶向下计数. 结点的高度:从叶结点开始,自底向上计数. 树的性质 ...
- C语言数据结构基础学习笔记——栈和队列
之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...
- JavaScript基础学习(三)—数组
一.数组简介 JavaScript数组的每一项都可以保存任何类型的数据,也就是说数组的第一个位置保存字符串,第二个位置可以保存数值,第三个位置可以保存对象,而且数组的大小是可以动态调整的,即可 ...
- Java基础学习(二)—数组
一.数组的概念 定义: 数组是存储同一种数据类型的多个元素的集合. 数组既可以存储基本数据类型,也可以存储引用数据类型. 格式: 格式1: 数据类型[] 数组名; 格式2: 数据类型 数组名[]; 这 ...
- <数据结构基础学习>(五)递归
一. 递归 本质上,将原来的问题,转化为更小的同样的问题 举例:数组求和 Sum(arr[0... n-1]) = arr[0] + Sum(arr[1...n-1]) 第二部分为更小的同一个问题 ...
随机推荐
- 福州大学软件工程1816 | W班 团队Alpha阶段成绩汇总排名(第9、10次作业)
写在前面 汇总成绩排名链接 1.作业链接 第九次作业--项目Alpha冲刺(团队) 第十次作业--事后诸葛亮(团队) 2.评分准则 本次作业包括现场Alpha答辩评分(映射总分为100分)+博客分(总 ...
- Java参数是值传递还是引用传递?
先来看看参数是如何传递的. 一.参数的传递 1.基本类型的参数传递 public static void main(String[] args) { int a = 1; fun(a); } priv ...
- 非常详细的Docker学习教程
一.Docker 简介 Docker 两个主要部件: Docker: 开源的容器虚拟化平台 Docker Hub: 用于分享.管理 Docker 容器的 Docker SaaS 平台 -- Docke ...
- rem 适配
postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem lib-flexible 用于设置 rem 基准值 一.webpact postcss 插件将px转化为rem单 ...
- html5 datalist 选中option选项后的触发事件
使用input + datalist 实现自动补全功能,其中datalist中的内容是根据input输入的内容动态变换的,代码如下 <!DOCTYPE HTML> <html> ...
- 用mescroll实现无限上拉增加数据,下拉刷新数据 (学习笔记)
最近自己做一个web app需要用到上拉查询下页数据,网上看了很多很多帖子,发现并不能快速的套用,总是会出现各种问题无法使用,于是无奈自己跑去看了官方api文档,终于做了出来,至此做个笔记,以后用到可 ...
- 运维常用mysql语句
1..select @@version; ##查询当前mysql的版本. 2. show variables like 'port';##查看mysql实例的端口. 3.show variables ...
- 阿里p3c(代码规范,eclipse插件、模版,idea插件)
阿里p3c 一.说明 代码规范检查插件p3c,是根据<阿里巴巴Java开发手册>转化而成的自动化插件. (高级黑:P-3C“Orion”,反潜巡逻机,阿里大概取p3c先进,监测,发现潜在问 ...
- Scrapy网络爬虫框架的开发使用
1.安装 2.使用scrapy startproject project_name 命令创建scrapy项目 如图: 3.根据提示使用scrapy genspider spider_name dom ...
- vue-cli(vue脚手架)
vue-cli用于自动生成vue+webpack项目. 安装webpack:npm install webpack -g 检查webpack是否安装成功和版本:webpack -v 如果是webpac ...