package com.lianbiao.java;
//707. 设计链表
class MyLinkedList {
/*
* 举例:
* 1 2 3 4 5 val
* 0 1 2 3 4 index
*/
//size存储链表元素的个数
int size;
//虚拟头结点
ListNode head;
//构造器
public MyLinkedList() {
size = 0;
head = new ListNode(0); //head值为0
}
//get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1
public int get(int index) {
//如果index非法,返回-1
if(index < 0 || index >= size) {//注意,index表示链表的编号,链表的编号从首元素开始0,1,2,3,...
return -1;
}
ListNode currentNode = head;//定义辅助指针来查找
for(int i = 0; i <= index; i++) {//如查找index = 1,则currentNode需要移动两次
currentNode = currentNode.next;
}
return currentNode.val;
}
//addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
public void addAtHead(int val) {
addAtIndex(0, val);
}
//addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
public void addAtTail(int val) {
addAtIndex(size, val);
}
/*
* 在链表中的第 index个节点之前添加值为 val的节点。
* 1.如果 index 等于链表的长度,则该节点将附加到链表的末尾。
* 2.如果 index 大于链表长度,则不会插入节点。
* 3.如果index小于0,则在头部插入节点。
*/
public void addAtIndex(int index, int val) {
if(index > size) {//2.如果 index 大于链表长度,则不会插入节点。
return;
}
if(index < 0) {//3.在头部插入结点,也就意味着在index=0时插入结点,下面的函数会找到index=0处结点的前驱结点
index = 0;
}
size++;//下面的操作是插入结点,所以让size+1,size++放在插入前后都行
//找到要插入节点的前驱
ListNode pred = head;//辅助结点 用来查找
for(int i = 0; i < index ; i++) {//例如index等于2时,需要找到index=1处,则pred需移动2次
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
//deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
public void deleteAtIndex(int index) {
if(index < 0 || index >= size) {
return;
}
size--;
ListNode pred = head;//定义辅助结点
for(int i = 0; i < index; i++) {//找到删除结点的前驱
pred = pred.next;
}
pred.next = pred.next.next;
}
}
//结点类
class ListNode{
int val;
ListNode next;
public ListNode() {
super();
}
public ListNode(int val) {
super();
this.val = val;
}
}