线性表:
线性表是具有n个相同元素类型的有限序列(n>=0)
线性表一般会有索引 0 1 2 3 .....
a1 是首节点(首元素),an是 尾结点(尾元素)
a1是a2的前驱,a2是a1 的后继
常见的线性表:
数组、链表、栈、队列、哈希表(散列表)
在很多编程语言中,数组都有个致命的缺点:无法动态修改容量。
实际开发中,我们更希望数组的容量是可以动态改变的。
下面自己实现一个动态数组:
// 动态数组
class ArrayList {
// 元素的数量
int size = 0;
// 所有的元素
List elements = [];
static const DEFAULT_CAPACITY = 10; // 初始化默认最小容量
static const ELEMENT_NOT_FOUND = -1; // 没有找到元素
ArrayList() {
elements = List.filled(DEFAULT_CAPACITY, null, growable: false);
}
ArrayList.array(int capacity) {
capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;
elements = List.filled(capacity, null, growable: false);
}
// 清除所有元素
clear() {
for (int i = 0; i < size; i++) {
elements[i] = null;
}
size = 0;
}
// size(){
// return size;
// }
// 是否为空
bool isEmpty() {
return size == 0;
}
// 是否包含某个元素
bool contains(var element) {
return indexOf(element) != ELEMENT_NOT_FOUND;
}
// 查看元素的索引
int indexOf(var element) {
if (element == null) {
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;
}
void add(var element) {
add2(size, element);
}
void add2(int index, var element) {
rangeCheckForAdd(index);
ensureCapacity(size + 1);
for (int i = size; i > index; i--) {
elements[i] = elements[i - 1];
}
elements[index] = element;
size++;
}
// 保证要有capacity的容量
void ensureCapacity(int capacity) {
int oldCapacity = elements.length;
if (oldCapacity >= capacity) return;
// 新容量为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
List newElements = List.filled(newCapacity, null, growable: false);
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements;
print("${oldCapacity}扩容为${newCapacity}");
}
void rangeCheckForAdd(int index) {
if (index < 0 || index > size) {
outOfBounds(index);
}
}
void outOfBounds(int index) {
throw new Exception("Index:$index Size:$size");
}
void rangeCheck(int index) {
if (index < 0 || index >= size) {
outOfBounds(index);
}
}
// 获取index位置的元素
Object get(int index) {
rangeCheck(index);
return elements[index];
}
// 设置index位置的元素
Object set(int index, var element) {
rangeCheck(index);
Object old = elements[index];
elements[index] = element;
return old;
}
// 删除index位置的元素
Object remove(int index) {
rangeCheck(index);
Object old = elements[index];
for (int i = index + 1; i < size; i++) {
elements[i - 1] = elements[i];
}
elements[--size] = null;
return old;
}
}
void add(int index, var element) 方法涉及到数组扩容。
Object remove(int index) 涉及到 元素移动,要好好看一下。
clear() 中释放对象 elements[i] = null;
其他方法都好理解
更多文章请关注我:
-
我的个人今日头条主页:www.toutiao.com/c/user/toke…
-
我的微信公众号:
- 我的掘金主页: juejin.cn/user/118789…