package java_03_06;
// 双向链表的节点, 需要记录 next 和 prev
class Node {
int val;
Node prev = null;
Node next = null;
public Node(int val) {
this.val = val;
}
}
// 实现一个双向链表
public class myLinkedList {
// 记录头结点的位置.
private Node head;
// 记录尾节点的位置.
private Node tail;
// 链表的元素个数. (空间换时间)
private int length = 0;
public myLinkedList() {
// 此处没有使用傀儡节点.
head = null;
tail = null;
}
public int length(myLinkedList head) {
return this.length;
}
public Node getNode(int index) {
if (index < 0 || index >= length) {
return null;
}
Node cur = head;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur;
}
// 插入节点
// 头插
public void addFirst(int val) {
Node newNode = new Node(val);
if (head == null) {
head = newNode;
tail = newNode;
length++;
return;
}
newNode.next = head;
head.prev = newNode;
head = newNode;
length++;
return;
}
// 尾插
public void addLast(int val) {
Node newNode = new Node(val);
if (head == null) {
head = newNode;
tail = newNode;
length++;
return;
}
tail.next = newNode;
newNode.prev = tail;
tail = newNode;
length++;
return;
}
// 指定位置插入
public void add(int index, int val) {
if (index < 0 || index > length) {
return;
}
if (index == 0) {
addFirst(val);
}
Node newNode = new Node(val);
// 考虑一般的情况
// 此时需要先找到 下标 => 节点~
Node nextNode = getNode(index);
// 接下来需要往 pos 之前插入 newNode
// 咱们的目的是让新节点插入完毕后, 下标就是 index
Node prevNode = nextNode.prev;
prevNode.next = newNode;
newNode.prev = prevNode;
newNode.next = nextNode;
nextNode.prev = newNode;
length++;
return;
}
public void removeFirst() {
if(head==null){
return ;
}
if (head.next==null){
head=null;
tail=null;
length=0;
return ;
}
Node nexthead=head.next;
nexthead.prev=null;
head=nexthead;
length--;
return;
}
public void removeLast() {
if(head==null){
return ;
}
if (head.next==null){
head=null;
tail=null;
length=0;
return ;
}
Node prevnode=tail.prev;
prevnode.next=null;
tail=prevnode;
length--;
return;
}
public void removeByIndex(int index) {
if (index < 0 || index >= length) {
return;
}
// 头删和尾删需要修改 head 和 tail
if (index == 0) {
// 头删
// 特殊处理
removeFirst();
return;
}
if (index == length - 1) {
// 尾删
// 特殊处理
removeLast();
return;
}
Node toRemove = getNode(index);
Node preNode=toRemove.prev;
Node nextNode=toRemove.next;
preNode.next=nextNode;
nextNode.prev=preNode;
length--;
return;
}
public void removeByValue(int val) {
int index = indexOf(val);
if (index == -1) {
return;
}
removeByIndex(index);
}
private int indexOf(int val) {
Node cur=head;
int i=0;
for (i=0;i<length;i++){
if(cur.val==val){
return i;
}
else{
cur=cur.next;
}
}
return -1;
}
// 查找
public int get(int index) {
if (index < 0 || index >= length) {
throw new ArrayIndexOutOfBoundsException();
}
return getNode(index).val;
}
// 修改
public void set(int index, int value) {
if (index < 0 || index >= length) {
throw new ArrayIndexOutOfBoundsException();
}
Node node = getNode(index);
node.val = value;
}
public void print(myLinkedList list){
Node cur=head;
while (cur.next!=null){
System.out.printf("%d<->",cur.val);
cur=cur.next;
}
if (cur.next==null){
System.out.printf("%d",cur.val);
}
System.out.println();
}
}
测试:
public class Test {
public static void main(String[] args) {
myLinkedList list=new myLinkedList();
list.addFirst(4);
list.addFirst(3);
list.addFirst(2);
list.addFirst(1);
list.addLast(5);
list.addLast(6);
list.addLast(7);
list.addLast(8);
list.addLast(9);
list.print(list);
//1<->2<->3<->4<->5<->6<->7<->8<->9
list.removeFirst();
list.print(list);
//2<->3<->4<->5<->6<->7<->8<->9
list.removeLast();
list.print(list);
//2<->3<->4<->5<->6<->7<->8
list.removeByIndex(1);
list.print(list);
//2<->4<->5<->6<->7<->8
list.removeByIndex(4);
list.print(list);
//2<->4<->5<->6<->8
list.removeByValue(8);
list.print(list);
//2<->4<->5<->6
list.set(1,6);
list.print(list);
//2<->6<->5<->6
}
}