0
点赞
收藏
分享

微信扫一扫

数据结构之线性表:动态数组



文章目录

  • ​​一、线性表初步认识​​
  • ​​1.常见数据结构​​
  • ​​2.线性表​​
  • ​​3.数组​​
  • ​​二、动态数组的设计​​
  • ​​1.构造方法的设计​​
  • ​​2.返回元素个数 size()​​
  • ​​3.判断数组元素是否为空 isEmpty()​​
  • ​​4.查看元素索引 indexOf(E element)​​
  • ​​5.对下标是否合法的判断​​
  • ​​6.判断是否需要扩容的方法 ensureCapacity​​
  • ​​7.添加元素的方法 add​​
  • ​​8.清除所有元素 clear​​
  • ​​9.判断数组是否包含某个元素​​
  • ​​10获取某个索引位置的元素 get(int index)​​
  • ​​11.修改某个索引位置的元素​​
  • ​​12.删除某个位置的元素 remove​​
  • ​​13.打印动态数组​​

一、线性表初步认识

1.常见数据结构

在讲线性表之前,我们要先对数据结构有一定的了解

数据结构是计算机存储、组织数据的形式

数据结构之线性表:动态数组_线性表

常见的数据结构有集合结构、线性结构、树形结构、图形结构

  • 线性结构
  • 数组
  • 链表
  • 队列
  • 哈希表(散列表)
  • 树形结构
  • 二叉树
  • AVL树
  • 红黑树
  • B树
  • Trie
  • 哈夫曼树
  • 并查集
  • 图形结构
  • 邻接矩阵
  • 邻接表

2.线性表

线性表是具有n个相同类型元素的有限序列(n>=0)

数据结构之线性表:动态数组_数组_02

3.数组

  • 数组是一种顺序存储的线性表,所有元素的内存地址是连续的

数据结构之线性表:动态数组_算法_03

数组是申请连续的空间

但是而且一旦申请了空间,那么它的容量就无法改变了,显然不符合我们的要求,我们肯定是希望数组的容量可以根据我们的需求而发生变化,因此,我们可以采取动态数组来解决这种问题

二、动态数组的设计

数据结构之线性表:动态数组_算法_04

在设计相关方法之前,我们先来定义相关属性

  • size:用来表示动态数组里面的元素个数
  • elements:数组
  • DEFAULT_CAPACITY :数组默认容量
  • ELEMENT_NOT_FOUND:没有找到数组中的元素,就返回这个值
    具体的方法在后文介绍
public class ArrayList<E> {
/**
* 元素的数量
*/
private int size;
/**
* 所有的元素
*/
private E[] elements;

private static final int DEFAULT_CAPACITY = 10;
private static final int ELEMENT_NOT_FOUND = -1;
}

1.构造方法的设计

  • capacity代表的是我们想要给动态数组多少容量
  • 默认容量为10
  • 如果我们给的容量小于默认容量,那么数组的容量就是默认容量
  • 如果我们给的容量大默认容量,那么数组的容量就是我们给的容量
public ArrayList(int capaticy) {
capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
elements = (E[]) new Object[capaticy];
}

public ArrayList() {
this(DEFAULT_CAPACITY);
}

2.返回元素个数 size()

/**
* 元素的数量
* @return
*/
public int size() {
return size;
}

3.判断数组元素是否为空 isEmpty()

  • 数组元素个数为0就代表数组为空
/**
* 判断是否为空
*/
public boolean isEmpty() {
return size == 0;
}

4.查看元素索引 indexOf(E element)

  • 我们可以遍历动态数组,然后把查找的元素和数组里面的元素一一比较
  • 因为数组可以存储任何类型的值,所以可能存储的是对象,我们可以用equals方法来比较
  • 要先判断查找的元素是否为空,因为如果值为空,调用equals方法会出现空指针异常,如果element为空,就使用==
  • 如果不为空,使用equals方法来比较
/**运行存储null
* 查看元素的索引
* @param element
* @return
*/
public int indexOf(E element) {
if (element == null) { // 1
for (int i = 0; i < size; i++) {
if (elements[i] == null) return i;
}
} else {
for (int i = 0; i < size; i++) {
if (element.equals(elements[i])) return i; // n
}
}
return ELEMENT_NOT_FOUND;
}

5.对下标是否合法的判断

private void outOfBounds(int index) {
throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
}

private void rangeCheck(int index) {
if (index < 0 || index >= size) {
outOfBounds(index);
}
}

private void rangeCheckForAdd(int index) {
if (index < 0 || index > size) {
outOfBounds(index);
}
}

6.判断是否需要扩容的方法 ensureCapacity

  • 如果原来的数组容量>=size+1,则不需要扩容
  • 否则需要扩容
  • 这个方法主要是为后面添加元素服务的
/**
* 确保有足够容量
*/
private void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
/**
* 此时不需要扩容
*/
if (oldCapacity >= capacity) {
return;
}
//扩容后,新容量为原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
E[] newElements=(E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i]=elements[i];
}
elements=newElements;
System.out.println(oldCapacity+"扩容为: "+newCapacity);

}

7.添加元素的方法 add

  • 在指定位置添加元素
  • 添加元素时,先判断索引是否合法
  • 然后判断是否需要扩容
  • 然后再进行添加元素
  • 记得size要加1
/**
* 在index位置插入一个元素
* @param index
* @param element
*/
public void add(int index, E element) {
rangeCheckForAdd(index);

ensureCapacity(size + 1);

for (int i = size; i > index; i--) {
elements[i] = elements[i - 1];
}
elements[index] = element;
size++;
}
  • 在数组末尾添加元素
/**
* 添加元素到尾部
* @param element
*/
public void add(E element) {
add(size, element);
}

8.清除所有元素 clear

public void clear() {
for (int i = 0; i < size; i++) {
elements[i] = null;
}
size = 0;
}

9.判断数组是否包含某个元素

  • 因为前面已经有了查看元素索引的方法
  • 如果没有这个元素,返回的是ELEMENT_NOT_FOUND
  • 我们只需要调用indexOf方法就可以进行判断了
public boolean contains(E element) {
return indexOf(element) != ELEMENT_NOT_FOUND;
}

10获取某个索引位置的元素 get(int index)

public E get(int index) {
rangeCheck(index);
return elements[index];
}

11.修改某个索引位置的元素

最后返回修改前的元素值

public E set(int index, E element) {
rangeCheck(index);

E old = elements[index];
elements[index] = element;
return old;
}

12.删除某个位置的元素 remove

public E remove(int index) {
rangeCheck(index);

E old = elements[index];
for (int i = index + 1; i < size; i++) {
elements[i - 1] = elements[i];
}
elements[--size] = null;
return old;
}

13.打印动态数组

@Override
public String toString() {
// size=3, [99, 88, 77]
StringBuilder string = new StringBuilder();
string.append("size=").append(size).append(", [");
for (int i = 0; i < size; i++) {
if (i != 0) {
string.append(", ");
}

string.append(elements[i]);

// if (i != size - 1) {
// string.append(", ");
// }
}
string.append("]");
return string.toString();
}
}



举报

相关推荐

0 条评论