链表
设计链表
707. 设计链表 - 力扣(LeetCode) (leetcode-cn.com)
class MyLinkedList {
int val;
MyLinkedList next;
MyLinkedList pre;
public MyLinkedList() {
this.val = 0;
this.next = null;
this.pre = null;
}
public MyLinkedList(int Aval) {
this.val = Aval;
this.next = null;
this.pre = null;
}
public int get(int index) {
MyLinkedList p =this.next;
while (--index >= 0 && p!=null) {
p = p.next;
}
if (p == null)
return -1;
else
return p.val;
}
public void addAtHead(int val) {
MyLinkedList p = new MyLinkedList(val);
if (this.next == null) {//此时只有头节点,链表为空
this.next = p;
p.pre = this;
}
else {
MyLinkedList q = this.next;
p.next = q;
p.pre = this;
this.next = p;
q.pre = p;
}
}
public void addAtTail(int val) {
MyLinkedList q = this;
while (q.next != null) {
q = q.next;
}
MyLinkedList p = new MyLinkedList(val);
q.next = p;
p.pre = q;
}
public void addAtIndex(int index, int val) {
if (index <= 0) {
this.addAtHead(val);
}
else {
MyLinkedList p =this;
MyLinkedList q = new MyLinkedList(val);
while (--index >= 0 && p.next!=null) {//注意判断插入的位置是否存在。长度为n的链表有n+1个插入位置
p = p.next;
}
if (index == -1) {
if (p.next == null) {
p.next = q;
q.pre = p;
}
else {
MyLinkedList r = p.next;
q.next = r;
r.pre = q;
p.next = q;
q.pre = p;
}
}
}
}
public void deleteAtIndex(int index) {
MyLinkedList p =this;
while (--index >= 0 && p.next!=null) {
p = p.next;
}
if (p.next != null) {//可以删除
MyLinkedList q = p.next; //被删除的元素
if (q.next == null) {//被删除的是最后一个
p.next = null;
}
else {
p.next = q.next;
q.next.pre = p;
}
}
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
设计链表看似基础,实际还是有一些坑的。
我个人不太同意在链表里加一个size描述链表长度的做法,感觉有点修改数据结构的意思。所以判断是否超出,都是直接遍历,以下是重点部分。
- 首先,长度为n的链表实际上有n+1个插入位,也就是说,判断插入位的时候,应当加一
- 其次,在删除一个结点的时候,实际上是到这个结点的pre结点