数据结构基础
- 数据结构研究的是数据如何在计算机中进行组织和存储,使得我们可以高效的获取数据或者修改数据
- 数据结构类型
- 线性结构:数组、栈、队列、链表
- 树结构:红黑树、二叉树、AVL
- 还有其他结构比如图
- 数据结构的应用
- MySql中的B+tree
- JAVA中的HashMap的红黑树
- 文件压缩算法,哈夫曼算法
动态数组
- 数组最大的有点:快速查询,但是不能动态扩容
- 创建一个可以动态变化的数组 定义一个size指向最后一个元素的后面一个元素,capacity表示数组的容量
package com.frank;
public class MyArray<E> {
private int nextIndex;
private E[] data;
private static int initCapacity = 10;
public MyArray(int capacity) {
data = (E[])new Object[capacity];
nextIndex = 0;
}
public MyArray() {
this(initCapacity);
}
public int size() {
return nextIndex;
}
public boolean isEmpty() {
return nextIndex == 0;
}
public void addLast(E item) {
add(nextIndex, item);
}
public void addFirst(E item) {
add(0, item);
}
public void add(int index, E item) {
if (index < 0 || index > nextIndex) {
throw new IllegalArgumentException("index error");
}
if (nextIndex == data.length) {
resize(2 * data.length);
}
for (int i = nextIndex - 1; i > index - 1; i--) {
data[i+1] = data[i];
}
data[index] = item;
nextIndex ++;
}
public E get(int index) {
if (index < 0 || index >= nextIndex) {
throw new IllegalArgumentException("index illegal");
}
return data[index];
}
public void set(int index, E item) {
if (index < 0 || index >= nextIndex) {
throw new ArrayIndexOutOfBoundsException("index illegal");
}
data[index] = item;
}
public E findElement(int index) {
return data[index];
}
public int findIndex(E item) {
for (int i = 0; i < nextIndex; i++) {
if (data[i].equals(item)) {
return i;
}
}
return -1;
}
public boolean contains(E item) {
for (int i = 0; i < nextIndex; i++) {
if (item.equals(data[i])) {
return true;
}
}
return false;
}
public E remove(int index) {
if (index < 0 || index >= nextIndex) {
throw new ArrayIndexOutOfBoundsException("remove index error");
}
E item = data[index];
for (int i = index; i < nextIndex - 1; i++) {
data[i] = data[i + 1];
}
nextIndex --;
if (nextIndex == data.length / 4 && data.length / 2 != 0) {
resize(data.length / 2);
}
return item;
}
public E removeElement(E item) {
int index = findIndex(item);
return remove(index);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("MyArray size=%d capacity=%d\r\n", nextIndex, data.length));
sb.append('[');
for (int i = 0; i < nextIndex; i++) {
sb.append(data[i]);
if (i != nextIndex - 1) {
sb.append(",");
}
}
sb.append(']');
return sb.toString();
}
private void resize(int newCapacity) {
E[] newData = (E[])new Object[newCapacity];
for (int i = 0; i < nextIndex; i++) {
newData[i] = data[i];
}
data = newData;
}
}
操作 | 综合时间复杂度 |
---|
增加 | O(n) |
删除 | O(n) |
修改 | 带索引O(1),否则为O(n) |
查询 | 带索引O(1),否则为O(n) |
- 复杂度震荡
- 在执行一个扩容的操作时候,立马又执行了缩容的操作,体现在代码中的是addLast(扩容),removeLast(缩容),反复执行出现复杂度震荡
public void add(int index, E item) {
if (index < 0 || index > nextIndex) {
throw new IllegalArgumentException("index error");
}
if (nextIndex == data.length) {
resize(2 * data.length);
}
for (int i = nextIndex - 1; i > index - 1; i--) {
data[i+1] = data[i];
}
data[index] = item;
nextIndex ++;
}
public E remove(int index) {
if (index < 0 || index >= nextIndex) {
throw new ArrayIndexOutOfBoundsException("remove index error");
}
E item = data[index];
for (int i = index; i < nextIndex - 1; i++) {
data[i] = data[i + 1];
}
nextIndex --;
if (nextIndex == data.length / 2) {
resize(data.length / 2);
}
return item;
}
- 数组优化
- 在执行removeLast缩容resize的时候过于着急,可以采取懒惰(Lazy)的解决方式:当数组的大小缩容到原来的容量的四分之一时,这个时候将数组的容量缩小为原来的一半