一.数组基础

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. html总结:表格中的文字居中

    <style> table { text-align:center; } </style>

  2. How to Configure Email Notification in Jenkins

    How to Configure Email Notification in Jenkins? - The Official 360logica Bloghttps://www.360logica.c ...

  3. vmware can not be closed virtual machine is busy

    VMware does not close when Windows Server 2003 ... |VMware Communities https://communities.vmware.co ...

  4. vsconsole

    一.安装 npm install vconsole 二. if (process.env.NODE_ENV === `development`) { const { logger } = requir ...

  5. [转帖]一段关于Unix与 Linux的暗黑史

    一段关于Unix与 Linux的暗黑史 https://blog.csdn.net/a343315623/article/details/51436715 微软曾经开发过 MS-DOS Xenix O ...

  6. [2018.05].NET Core 3 and Support for Windows Desktop Applications

    .NET Core 3 and Support for Windows Desktop Applications Richard 微软官网的内容...net 3.0 升级任务 任重道远 https:/ ...

  7. Js中instanceof 的用法

    在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”. ...

  8. 2017年前小纪(有关http的一些缓存理论知识)

    position的top和bottom的区别:前者基准点定在top,后者基准点定在bottom. for-in 遍历属性的顺序不确定 手机端,line-height对光标大小非常有影响 有些css3属 ...

  9. css繼承

    概念:就是上級設置了css屬性,下級默認有同樣的樣式,如果下級需要不一樣的樣式,那麼就需要單獨對下級設置. 範圍: font-family:字體 font-weight:粗細 font-size:尺寸 ...

  10. 八、.net core 通过数据库配置文件连接操作数据库

    一.创建DotNetCore项目 直接创建core项目并不勾选docker支持  二.nuget进行连接MySQL程序集的下载安装 1.MySql.Data.EntityFrameworkCore方式 ...