Java中contions_01数据结构和算法(Java描述)~ArrayList

本文介绍了线性表的概念和特点,特别关注了Java中的ArrayList数据结构。ArrayList是线性表的顺序存储结构,具备根据索引快速查询的优势,但也存在插入和删除效率低的缺点。文章通过讲解ArrayList的实现,包括添加、删除、获取元素等操作,以及扩容机制,帮助读者理解ArrayList的工作原理。
摘要由CSDN通过智能技术生成

01数据结构和算法(Java描述)~ArrayList

线性表

本章源码 提取码:ilul

线性表的概念

线性表属于最基本、最简单、也是最常用的一种数据结构,从逻辑上划分它属于线性结构。一 个线性表是由 n个具有相同特性的数据元素组成的有限序列,数据元素之间具有一种线性的或“一 对一”的逻辑关系,如下图所示:

22cfceb7cc339a4bad3d88849a66d6c7.png

从严谨的角度上来讲,线性表应该满足以下三个要求:

第一个数据元素没有直接前驱,这个数据元素被称为开始节点;

最后一个数据元素没有直接后继,这个数据元素被称为终端节点;

除了第一个和最后一个数据元素外,其它数据元素有且仅有一个直接前驱和一个直接后继。

线性表的特点:

顺序性

在线性表中,相邻数据元素之间存在着序偶关系,也就是存在着先后关系。

相同数据类型

在线性表中,每一个数据元素都属于相同数据类型。相同数据类型意味着在内存中存储时,每 个元素会占用相同的内存空间,便于后续的查询定位。

有限性

在线性表中,数据元素的个数 n 就是为线性表的长度,n是一个有限值。当 n=0 时线性表为空 表。在非空的线性表中每个数据元素在线性表中都有唯一确定的序号,例如第一个元素的序号是0, 第 i个元素的序号为i-1。在一个具有n>0个数据元素的线性表中,数据元素序号的范围是[0,n-1]。

线性表的存储结构

线性表拥有两种不同的存储结构,分别为:

顺序存储结构(顺序表):顺序表是采用一组地址连续的存储单元来依次存放线性表中的各个 元素。

b8b1535764c4517caf4dafe2de8f98f2.png

链式存储结构(链表):链表中的存储元素的地址不一定是连续的,元素节点中存放数据元素 以及相邻元素的地址信息。

b2051bebfcc18f8ce0367826de579280.png

顺序表

顺序表的特点:

顺序表根据索引查询元素的特点

因为顺序表(此处,也就是数组)的内存空间是连续的,并且存储的数据属于相同数据类型。 因此,我们可以通过数组的“首地址+索引”就能快速的找到数组中对应索引的元素值,从而得出数 组的优点:查找快。

46ed6ebb86bc361ef5aac9f0c1521558.png

索引操作数组原理:数组首地址 + 存放数据的字节数*索引。

顺序表删除元素的特点

需求:删除数组{11, 22, 33, 44, 55, 66}索引为2 的元素,删除后的数组为:{11, 22, 44, 55, 66}。

2c99a9abd28c6314990bce4bb1167094.png

实现步骤:

1.先检查数组是否需要扩容。如果数组的空间长度和数组添加元素个数相等,则需做扩容操作。

1.定义一个空间长度更大的新数组。

2.把原数组中的元素全部拷贝到新数组中。

3.让原数组指向新数组,也就是让原数组保存新数组的地址值。

2.把插入索引及其之后的元素往后挪动一位(从后往前挪动)。

3.把插入的元素赋值到插入索引的位置中。

顺序表优劣势的总结

优点:无须关心表中元素之间的关系,所以不用增加额外的存储空间;可以根据索引快速地操作表 中任意位置的元素,并且操作任何一个元素的耗时都是一样。

缺点:插入和删除操作需要移动大量元素。使用前需事先分配好内存空间,当线性表长度变化较大 时,难以确定存储空间的容量。分配空间过大会造成存储空间的巨大浪费,分配的空间过小,难以 适应问题的需求。

好了,理论知识就先说到这,我们先来实现以下本栏目的第一个数据结构,ArrayList

ArrayList

搭建项目框架

3c014f7ab0cc82d6d281dc7266d91505.png

List接口

package arraylist.List;

import arraylist.iterator.Iterator;

public interface List {

// ------- 添加 -------

void add(Object object);

// ------- 根据坐标删除 -------

void remove(int index);

// ------- 根据内容删除 -------

void removeobj(Object object);

// ------- 取出数据 -------

Object get(int index);

// ------- 求集合的长度 -------

int size();

// ------- 判断集合是否为空 -------

boolean isEmpty();

// ------- 根据内容找到元素坐标 -------

int IndexOf(Object object);

// ------- 判断元素是否存在 -------

boolean contions(Object object);

// ------- 根据坐标位置插入元素 -------

void add(int index, Object object);

// ------- 修改元素 -------

void replase(int index, Object object);

// ------- toString -------

String toString();

// ------- arraylist迭代器 -------

Iterator iterator();

}

Iterator接口

public interface Iterator {

boolean hasNext();

T next();

}

ArrayList实现类

package arraylist.ArrayList;

import arraylist.List.List;

import arraylist.iterator.Iterator;

public class ArrayList implements List {

public Object []elementData; //数组的引用

private int size; //集合的大小,并非elementData.length

//如果用户没设置大小就初始为10

public ArrayList(){

this(10); //数组大小初始为10

}

//集合的大小等于用户设置的大小

public ArrayList(int len){

elementData = new Object[len];

}

// 数组的扩容

void grow(){

//创建新的数组

Object []newArr = new Object[elementData.length + (elementData.length >> 1)];//扩容1.5倍

for(int i = 0; i < size; i++){

//将原来数组的内容存到新数组里

newArr[i] = elementData[i];

}

elementData = newArr;

}

//在集合的尾部添加元素

public void add(Object object) {

//如果数组长度不够就调用扩容

if(elementData.length <= size){

grow();

}

elementData[size] = object;

//大小增加一位

size++;

}

//根据坐标删除元素

public void remove(int index) {

//判断用户是否输入错误

if(index<0|| index >size-1){

throw new IndexOutOfBoundsException("索引越界"+index);

}

Object element=elementData[index];

// 向前移动元素

for (int i = index; i

elementData[i]=elementData[i+1];

}

// 最后一个元素置为空

elementData[size-1]=null;

size--;

}

//根据元素删除

public void removeobj(Object object) {

int index = IndexOf(object);

//判断用户是否输入错误!

if(index<0){

throw new NullPointerException();

}

remove(index);

}

//根据坐标得到元素

public Object get(int index) {

return elementData[index];

}

//求集合的长度

public int size() {

return size;

}

//判断是否为空

public boolean isEmpty() {

return size == 0;

}

//根据元素找到坐标

public int IndexOf(Object object) {

int i = 0;

while(i < size){

if(elementData[i].equals(object)){

break;

}

i++;

}

return i;

}

//判断元素是否存在

public boolean contions(Object object) {

boolean flag = false;

for(int i = 0; i < size; i++){

if(elementData[i].equals(object)){

flag = true;

break;

}

}

return flag;

}

//根据坐标位置添加元素

public void add(int index, Object object) {

if(size >= elementData.length){

grow();

}

for(int i = size; i > index; i--){

elementData[i] = elementData[i - 1];

}

elementData[index] = object;

size++;

}

//修改元素

public void replase(int index, Object object) {

elementData[index] = object;

}

//重写toString

public String toString(){

StringBuilder str = new StringBuilder("[");

for(int i = 0; i < size; i++){

//判断是否到了最后一位,如果到了就不添加,

if(i == size - 1){

str.append(elementData[i]);

break;

}else{

str.append(elementData[i] + ",");

}

}

str.append("]");

return str.toString();

}

// ------- 迭代器 -------

public Ite iterator(){

return new Ite();

}

private class Iteimplements Iterator {

int cursor = 0; //指向当前元素,默认是0

public ArrayList arr = new ArrayList();

public boolean hasNext() {

return cursor != size;

}

public T next() {

int i = cursor; //保留当前值

cursor++;//自增

// 进行判断,防止越界

if (i > size) {

throw new RuntimeException("没有元素");

}

return (T) elementData[i];

}

}

}

Test测试

package arraylist.test;

import arraylist.ArrayList.ArrayList;

import arraylist.List.List;

import arraylist.iterator.Iterator;

public class Test {

public static void main(String[] args) {

List list = new ArrayList();

//增加测试

for(int i = 1; i < 19; i++){

list.add(i);

}

list.add(9,564);

//迭代器测试

Iterator iterator = list.iterator();

while(iterator.hasNext()){

System.out.print(iterator.next() + " ");

}

//其他方法测试

System.out.println("是否为空: " + list.isEmpty());

System.out.println("长度: " + list.size());

System.out.println("元素 15 是否存在: " + list.contions(15));

System.out.println("元素 564的坐标: " + list.IndexOf(564));

System.out.println("将坐标3元素 改成 23: "); list.replase(3,23);

System.out.println("取出坐标7: " + list.get(7));

System.out.println("删除坐标5: " ); list.remove(5);

System.out.println("删除元素 564: "); list.removeobj(564);

//最后toString

System.out.println(list.toString());

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值