3、动态数组
1、动态数组
在这里新创建一个数组类,对 Java 语言中的原始数组进行封装,使得它可以动态的扩容和缩容
Java 语言中也有类似的实现,叫 ArrayList,我们创建的数组类是它的简化版本,下面是代码实现
/**
* 动态数组
*/
public class Array<E> {
private E[] data;
private int size;
public Array(int capacity) {
data = (E[]) new Object[capacity];
size = 0;
}
public Array() {
this(10);
}
public Array(E[] arr) {
data = Arrays.copyOf(arr, arr.length);
size = arr.length;
}
public int getSize() {
return size;
}
public int getCapacity() {
return data.length;
}
public boolean isEmpty() {
return size == 0;
}
/**
* 添加
*/
public void add(int index, E e) {
if (index < 0 || index > size) throw new RuntimeException("need 0 <= index <= size");
if (size == data.length) resize(data.length * 2);
System.arraycopy(data, index, data, index + 1, size - index);
data[index] = e;
size++;
}
public void addFirst(E e) {
add(0, e);
}
public void addLast(E e) {
add(size, e);
}
/**
* 删除
*/
public E remove(int index) {
if (index < 0 || index >= size) throw new RuntimeException("need 0 <= index < size");
E ret = data[index];
System.arraycopy(data, index + 1, data, index, size - index - 1);
size--;
data[size] = null;
if (size == data.length / 4 && data.length / 2 != 0) resize(data.length / 2);
return ret;
}
public E removeFirst() {
return remove(0);
}
public E removeLast() {
return remove(size - 1);
}
public void removeElement(E e) {
int index = find(e);
if (index != -1) remove(index);
}
/**
* 修改
*/
public void set(int index, E e) {
if (index < 0 || index > size) throw new RuntimeException("need 0 <= index <= size");
data[index] = e;
}
/**
* 查看
*/
public E get(int index) {
if (index < 0 || index >= size) throw new RuntimeException("need 0 <= index < size");
return data[index];
}
public E getFirst() {
return get(0);
}
public E getLast() {
return get(size - 1);
}
public boolean contains(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) return true;
}
return false;
}
public int find(E e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) return i;
}
return -1;
}
/**
* 动态数组
*/
private void resize(int newCapacity) {
E[] newData = (E[]) new Object[newCapacity];
System.arraycopy(data, 0, newData, 0, size);
data = newData;
}
public void swap(int a, int b) {
if (a < 0 || a >= size || b < 0 || b >= size) {
throw new IllegalArgumentException("Swap failed, require 0 <= index < size");
}
E k = data[a];
data[a] = data[b];
data[b] = k;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Array: size = %d, capacity = %d\n", size, data.length));
sb.append('[');
for (int i = 0; i < size; i++) {
sb.append(data[i]);
if (i != size - 1) sb.append(", ");
}
sb.append(']');
return sb.toString();
}
}
2、resize 复杂度分析
3、复杂度震荡
4、数组栈
很容易基于上面的动态数组来实现栈,并且 push、pop、peek 的复杂度都是 O(1) 级别的
/**
* 数组栈
*/
public interface Stack<E> {
void push(E e);
E pop();
E peek();
int getSize();
boolean isEmpty();
}
public class ArrayStack<E> implements Stack<E> {
private final Array<E> array;
public ArrayStack() {
this.array = new Array<>();
}
public ArrayStack(int capacity) {
this.array = new Array<>(capacity);
}
@Override
public void push(E e) {
array.addLast(e);
}
@Override
public E pop() {
return array.removeLast();
}
@Override
public E peek() {
return array.getLast();
}
@Override
public int getSize() {
return array.getSize();
}
@Override
public boolean isEmpty() {
return array.isEmpty();
}
public int getCapacity() {
return array.getCapacity();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ArrayStack: [");
for (int i = 0; i < array.getSize(); i++) {
sb.append(array.get(i));
if (i != array.getSize() - 1) sb.append(", ");
}
sb.append("] Top");
return sb.toString();
}
}
5、数组队列
也很容易基于上面的动态数组来实现队列,enqueue 和 getFront 的复杂度都是 O(1) 级别的,但 dequeue 却是 O(n)
或许可以优化,使得 dequeue 的复杂度也是 O(1) 级别的
/**
* 数组队列
*/
public interface Queue<E> {
void enqueue(E e);
E dequeue();
E getFront();
int getSize();
boolean isEmpty();
}
public class ArrayQueue<E> implements Queue<E> {
private final Array<E> array;
public ArrayQueue() {
this.array = new Array<>();
}
public ArrayQueue(int capacity) {
this.array = new Array<>(capacity);
}
@Override
public void enqueue(E e) {
array.addLast(e);
}
@Override
public E dequeue() {
return array.removeFirst();
}
@Override
public E getFront() {
return array.getFirst();
}
@Override
public int getSize() {
return array.getSize();
}
@Override
public boolean isEmpty() {
return array.isEmpty();
}
public int getCapacity() {
return array.getCapacity();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ArrayQueue: Front [");
for (int i = 0; i < array.getSize(); i++) {
sb.append(array.get(i));
if (i != array.getSize() - 1) sb.append(", ");
}
sb.append("] Tail");
return sb.toString();
}
}
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17302701.html