数组和链表是什么?
数组是将元素顺序存储的的数据结构,查找快增删慢
而链表是将元素链式存储的数据结构,查找慢增删快
数组实现
基本数组
在Java中基本数组是由内部实现,利用数据类型+[]定义(不算严格意义上的数组,其只是开辟了一片连续的存储空间,每个下标指向对应的空间,只有存取操作)
int[] a;
String[] b;
完整数组
以下只完成了对数组简单的增删改查,其他功能如对下标的判断、扩容等功能可具体看ArrayList或Vector
class MyArray<E> {
private int size;
private Object[] array;
MyArray() {
this(10);
}
MyArray(int initialCapacity) {
array = new Object[initialCapacity];
}
public E get(int index) {
return (E) array[index];
}
public void set(int index, E value) {
array[index] = value;
}
public void add(int index, E value) {
System.arraycopy(array, index, array, index + 1, size - index);
array[index] = value;
size++;
}
public void remove(int index) {
System.arraycopy(array, index + 1, array, index, size - index - 1);
size--;
}
@NonNull
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
for (int i = 0; i < size; i++) {
if (i == size - 1) {
stringBuilder.append(array[i]);
}else {
stringBuilder.append(array[i] + ", ");
}
}
stringBuilder.append("]");
return stringBuilder.toString();
}
}
以下是测试代码
MyArray<Integer> myArray = new MyArray<>();
myArray.add(0, 0);
myArray.add(1, 1);
myArray.add(2, 2);
System.out.println(myArray);
System.out.println(myArray.get(0));
myArray.set(0, 3);
System.out.println(myArray);
myArray.add(1, 4);
System.out.println(myArray);
myArray.remove(1);
System.out.println(myArray);
链表实现
单向链表(包括头指针)
以下只完成了对单向链表的增删改查,其他功能具体可看LinkedList
class MyLinkList<E> {
private Node<E> first;
private int size;
private static class Node<E> {
E item;
Node<E> next;
Node(E element, Node<E> next) {
this.item = element;
this.next = next;
}
}
public void remove(int index) {
if (index == 0) {
Node<E> temp = first.next;
first.next = null;
first = temp;
} else {
Node<E> temp = first;
for (int i = 0; i < index - 1; i++) {
temp = first.next;
}
Node<E> remove = temp.next;
temp.next = remove.next;
remove.next = null;
}
size--;
}
public void add(int index, E value) {
if (size == 0) {
first = new Node<>(value, null);
} else if (index == 0) {
Node<E> newNode = new Node<>(value, first);
first = newNode;
} else {
Node<E> temp = first;
for (int i = 0; i < index - 1; i++) {
temp = first.next;
}
Node<E> newNode = new Node<>(value, temp.next);
temp.next = newNode;
}
size++;
}
public void set(int index, E value) {
Node<E> temp = first;
for (int i = 0; i < index; i++) {
temp = first.next;
}
temp.item = value;
}
public E get(int index) {
Node<E> temp = first;
for (int i = 0; i < index; i++) {
temp = first.next;
}
return temp.item;
}
@NonNull
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
Node<E> temp = first;
stringBuilder.append("[");
for (int i = 0; i < size; i++) {
if (i == size - 1) {
stringBuilder.append(temp.item);
} else {
stringBuilder.append(temp.item + ", ");
}
temp = temp.next;
}
stringBuilder.append("]");
return stringBuilder.toString();
}
}
以下为测试代码
MyLinkList<Integer> myLinkList = new MyLinkList<>();
myLinkList.add(0, 0);
myLinkList.add(1, 1);
myLinkList.add(2, 2);
System.out.println(myLinkList);
System.out.println(myLinkList.get(0));
myLinkList.set(0, 3);
System.out.println(myLinkList);
myLinkList.add(1, 4);
System.out.println(myLinkList);
myLinkList.remove(1);
System.out.println(myLinkList);
双向链表(包括头尾指针)
双向链表相比于单向链表,其节点多了个指向前节点的域,对其的增删需断开/链接前后节点
class MyDoublyLinkList<E> {
private Node<E> first;
private int size;
private Node<E> last;
private static class Node<E> {
E item;
Node<E> next;
Node<E> pre;
Node(Node<E> pre, E element, Node<E> next) {
this.pre = pre;
this.item = element;
this.next = next;
}
}
public void remove(int index) {
if (index == 0) {
Node<E> temp = first.next;
temp.pre = null;
first.next = null;
first = temp;
} else if (index == size - 1) {
Node<E> temp = last.pre;
temp.next = null;
last.pre = null;
last = temp;
} else {
Node<E> temp = first;
for (int i = 0; i < index; i++) {
temp = first.next;
}
temp.pre.next = temp.next;
temp.next.pre = temp.pre;
temp.pre = null;
temp.next = null;
}
size--;
}
public void add(int index, E value) {
if (size == 0) {
first = last = new Node<>(null, value, null);
} else {
if (index == 0) {
Node<E> newNode = new Node<>(null, value, first);
first.pre = newNode;
first = newNode;
} else if (index == size) {
Node<E> newNode = new Node<>(last, value, null);
last.next = newNode;
last = newNode;
} else {
Node<E> temp = first;
for (int i = 0; i < index; i++) {
temp = first.next;
}
Node<E> newNode = new Node<>(temp.pre, value, temp);
temp.pre.next = newNode;
temp.next.pre = newNode;
}
}
size++;
}
public void set(int index, E value) {
Node<E> temp = first;
for (int i = 0; i < index; i++) {
temp = first.next;
}
temp.item = value;
}
public E get(int index) {
Node<E> temp = first;
for (int i = 0; i < index; i++) {
temp = first.next;
}
return temp.item;
}
@NonNull
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
Node<E> temp = first;
stringBuilder.append("[");
for (int i = 0; i < size; i++) {
if (i == size - 1) {
stringBuilder.append(temp.item);
} else {
stringBuilder.append(temp.item + ", ");
}
temp = temp.next;
}
stringBuilder.append("]");
return stringBuilder.toString();
}
}
测试代码同单向链表
MyDoublyLinkList<Integer> myLinkList = new MyDoublyLinkList<>();
myLinkList.add(0, 0);
myLinkList.add(1, 1);
myLinkList.add(2, 2);
System.out.println(myLinkList);
System.out.println(myLinkList.get(0));
myLinkList.set(0, 3);
System.out.println(myLinkList);
myLinkList.add(1, 4);
System.out.println(myLinkList);
myLinkList.remove(1);
System.out.println(myLinkList);