一.数组基础

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. scrapy之管道

    scrapy之管道 通过管道将数据持久化到数据库中,企业中常见的数据库是MySQL,分布式爬取数据时只能讲数据存储到Redis装,还可以将数据存储到本地磁盘(即写入到本地文件中). 未完待续... 0

  2. Python_面向对象_单例模式

    class A(object): pass a1 = A() a2 = A() print(a1 == a2)print(id(a1))print(id(a2)) 结果: False 23257231 ...

  3. Django的模板语言

      Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. ...

  4. C#设计模式之2:单例模式

    在程序的设计过程中很多时候系统会要求对于某个类型在一个应用程序域中只出现一次,或者是因为性能的考虑,或者是由于逻辑的要求,总之是有这样的需求的存在,那在设计模式中正好有这么一种模式可以来满足这样的要求 ...

  5. Velocity之初印象

    Velocity 模板引擎介绍 在现今的软件开发过程中,软件开发人员将更多的精力投入在了重复的相似劳动中.特别是在如今特别流行的 MVC 架构模式中,软件各个层次的功能更加独立,同时代码的相似度也更加 ...

  6. C# Note32: 查漏补缺

    (1)Using的三种使用方式 (2)C#详解值类型和引用类型区别 (3)c#中字段(field)和属性(property)的区别 (4)C#中的 int? int?:表示可空类型,就是一种特殊的值类 ...

  7. 用Python来操作redis 以及在Django中使用redis

    什么是Redis? Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值可以包 ...

  8. ubuntu18.04 安装 php7.2

    sudo apt-get install software-properties-common python-software-properties sudo add-apt-repository p ...

  9. python之路--内置常用模块

    一 . 简单的了解模块 你写的每一个py文件都是一个模块. 还有一些我们一直在使用的模块. buildins  内置模块. print, input. random  主要是和随机相关的的内容 ran ...

  10. 学习 Spring (一) Spring 介绍

    Spring入门篇 学习笔记 Spring 是什么 Spring 是一个轻量级的 IoC (控制反转)和 AOP (面向切面)的容器框架 框架与类库的区别 框架一般是封装了逻辑.高内聚的,类库则是松散 ...