链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
- 优点:无需处理固定容量的问题; 动态数据结构.
- 缺点:丧失随机访问的能力
单链表的具体实现
public class MyLink<T> {
class Node {
private T val;
private Node next;
public Node(T val) {
this.val = val;
this.next = null;
}
@Override
public String toString() {
return this.val.toString();
}
}
private Node head;
private int size;
public MyLink() {
this.head = null;
this.size = 0;
}
public boolean isEmpty() {
return this.size == 0;
}
public int getSize() {
return this.size;
}
public void addTail(T val) {
add(val, this.size);
}
public void addHead(T val) {
add(val, 0);
}
public void add(T val, int index) {
if (index > this.size || index < 0) {
throw new IllegalArgumentException("index错误");
}
Node node = new Node(val);
Node dummyHead = new Node(null);
dummyHead.next = head;
Node preNode = dummyHead;
for (int i = 0; i < index; i++) {
preNode = preNode.next;
}
node.next = preNode.next;
preNode.next = node;
this.size++;
head = dummyHead.next;
}
@Override
public String toString() {
StringBuilder sbl = new StringBuilder();
Node cur = head;
while (cur != null) {
sbl.append(cur + "==>");
cur = cur.next;
}
sbl.append("null");
return sbl.toString();
}
public boolean contains(T val) {
Node curNode = this.head;
while (curNode != null && !curNode.val.equals(val)) {
curNode = curNode.next;
}
return curNode != null;
}
public void set(int index, T val) {
if (index >= this.size || index < 0) {
throw new IllegalArgumentException("index错误");
}
Node curNode = head;
for (int i = 0; i < index; i++) {
curNode = curNode.next;
}
curNode.val = val;
}
public T get(int index) {
if (index >= this.size || index < 0) {
throw new IllegalArgumentException("index错误");
}
Node curNode = head;
for (int i = 0; i < index; i++) {
curNode = curNode.next;
}
return curNode.val;
}
public T getHead() {
return get(0);
}
public T getTail() {
return get(this.size - 1);
}
public T removeHead() {
return remove(0);
}
public T removeTail() {
return remove(this.size - 1);
}
public T remove(int index) {
if (index >= this.size || index < 0) {
throw new IllegalArgumentException("index错误");
}
Node dummyHead = new Node(null);
dummyHead.next = head;
Node curNode = dummyHead;
for (int i = 0; i < index; i++) {
curNode = curNode.next;
}
Node delNode = curNode.next;
T result = delNode.val;
curNode.next = delNode.next;
delNode.next = null;
this.size--;
head = dummyHead.next;
return result;
}
}
|