一.数组基础

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();
}

<数据结构基础学习>(一)数组的更多相关文章

  1. Java基础学习之数组基本属性和方法

    数组对于每一门编程语言都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同.Java语言中提供的数组是用来存储固定大小的同类型元素.你可以声明一个数组变量,如 int[100] 来代替直接 ...

  2. <数据结构基础学习>(四)链表 Part 1

    一.链表基础 动态数组.栈.队列底层都是依托静态数组实现的,靠resize来解决固定容量问题. 链表是真正的动态数据结构,是一种最简单的一种动态数据结构. 更深入的理解引用(或者指针). 更深入的理解 ...

  3. <数据结构基础学习>(三)Part 1 栈

    一.栈 Stack 栈也是一种线性的数据结构 相比数组,栈相对应的操作是数组的子集. 只能从一端添加元素,也只能从一端取出元素.这一端成为栈顶. 1,2,3依次入栈得到的顺序为 3,2,1,栈顶为3, ...

  4. <数据结构基础学习>(三)Part 2 队列

    一.队列 Queue 队列也是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另一端(队首)取出元素. (排队) 队列是一种先进先出的数据结构(先到先得)FIFO ...

  5. C语言数据结构基础学习笔记——树

    树是一种一对多的逻辑结构,树的子树之间没有关系. 度:结点拥有的子树数量. 树的度:树中所有结点的度的最大值. 结点的深度:从根开始,自顶向下计数. 结点的高度:从叶结点开始,自底向上计数. 树的性质 ...

  6. C语言数据结构基础学习笔记——栈和队列

    之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...

  7. JavaScript基础学习(三)—数组

    一.数组简介     JavaScript数组的每一项都可以保存任何类型的数据,也就是说数组的第一个位置保存字符串,第二个位置可以保存数值,第三个位置可以保存对象,而且数组的大小是可以动态调整的,即可 ...

  8. Java基础学习(二)—数组

    一.数组的概念 定义: 数组是存储同一种数据类型的多个元素的集合. 数组既可以存储基本数据类型,也可以存储引用数据类型. 格式: 格式1: 数据类型[] 数组名; 格式2: 数据类型 数组名[]; 这 ...

  9. <数据结构基础学习>(五)递归

    一. 递归 本质上,将原来的问题,转化为更小的同样的问题 举例:数组求和 Sum(arr[0... n-1]) = arr[0] + Sum(arr[1...n-1])  第二部分为更小的同一个问题 ...

随机推荐

  1. 多线程系列之十:Future模式

    一,Future模式 假设有一个方法需要花费很长的时间才能获取运行结果.那么,与其一直等待结果,不如先拿一张 提货单.获取提货单并不耗费时间.这里提货单就称为Future角色获取Future角色的线程 ...

  2. java随笔5 完整路径的应用

    不仅类,函数,甚至参数都可以获取完整路径

  3. 设置SQLServer数据库内存

    需要设置SQLServer数据库的内存配置.登录数据库,这里使用的是SQLServer2008,右键点击最上方的服务器名,在弹出的菜单中,点击属性] 打开服务器属性窗口.默认显示的是第一项[常规]内容 ...

  4. Golang的方法传递值应该注意的地方

    其实最近看了不少Golang接口以及方法的阐述都有一个地方没说得特别明白.就是在Golang编译隐式转换传递给方法使用的时候,和调用函数时的区别. 我们都知道,在我们为一个类型变量申明了一个方法的时候 ...

  5. Lodop纯文本英文-等符号自动换行问题

    ADD_PRINT_TEXT纯文本,宽度不够,高度足够,超宽会自动换行,高度不够会隐藏后面的内容.在超宽自动换行的时候,如果有-或()之类的,英文单词不拆分,或其他一些认为是不拆分的情况,会造成还没有 ...

  6. Windows & RabbitMQ:集群(clustering) & 高可用(HA)

    描述:我们需要配置三台服务器:ServerA, ServerB, ServerC 注意事项: 所有的服务器的Erlang版本,RabbitMQ版本必须一样 服务器名大小写敏感 Step 1:安装Rab ...

  7. iframe与src一个性质 当js中修改了src的值后会重新向后台发送请求 ;为了防止浏览器缓存问题 当我们修改src时候 需要添加不同的值 这样浏览器就不会从缓存中取值 而是重新发起后台请求

  8. java 中的包概念

    Java 中的包package, 就是电脑中的文件夹.我们平时在工作中,文件太多时,都会新建文件夹进行分类管理,java 中的包也是类似的道理,当我们的类太多时,也需要进行分类管理,这时我们就会把类文 ...

  9. codeforces231C

    To Add or Not to Add CodeForces - 231C A piece of paper contains an array of n integers a1, a2, ..., ...

  10. micro-fusion & macro-fusion

    micro-fusion 随着技术的发展,CPU内部指令处理单元(execution unit)以及端口(port)增多,在Pentium 4的时候,发出到Execution Unit的μops的th ...