单链表(采用虚拟头节点操作)
//单链表
public class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
}
class MyLinkedList {
int size; //链表的长度,即记录链表的元素个数
ListNode head; //虚拟的头节点
//初始化
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
//获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
public int get(int index) {
//因为节点是从0开始算,所以有等于号
if(index < 0 || index >= size ){
return -1;
}
ListNode currentNode = head;
//因为包括一个虚拟的头节点,所以共有index+1个节点
for(int i = 0; i <= index ; i++){
currentNode = currentNode.next;
}
return currentNode.val;
}
public void addAtHead(int val) {
int index = 0;
addAtIndex(index,val);
}
public void addAtTail(int val) {
//这里是需要index等于size还是index等于size减一呢?
//因为是从0开始的,所以下标是到size--,末尾的加一个节点的下标就是size
int index = size;
addAtIndex(index,val);
}
public void addAtIndex(int index, int val) {
//index的判断
if(index > size){
return;
}
if (index < 0) {
index = 0;
}
size++; //长度增加
//找到插入节点的前驱
ListNode pre = head;
for(int i = 0; i < index; i++){
pre = pre.next;
}
ListNode addNode = new ListNode(val);
addNode.next = pre.next;
pre.next = addNode;
}
public void deleteAtIndex(int index) {
//index的判断
if(index < 0 || index >= size){
return;
}
if(index < 0){
index = 0;
}
size--; //长度减少
//找到链表的前驱
ListNode pre = head;
for(int i = 0; i < index; i++){
pre = pre.next;
}
pre.next = pre.next.next;
}
}
双链表(采用虚拟头节点操作)
//双链表
public class ListNode {
int val;
ListNode next;
ListNode prev;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
}
class MyLinkedList {
int size; //链表的长度,即记录链表的元素个数
ListNode head; //虚拟的头节点
ListNode tail; //虚拟的尾节点
//初始化
public MyLinkedList() {
size = 0;
head = new ListNode(0);
tail = new ListNode(0);
//这里很重要
head.next = tail;
tail.prev = head;
}
//获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
public int get(int index) {
//判断index是否有效
if(index < 0 || index >= size ){
return -1;
}
ListNode currentNode = head;
//判断哪边快,减少执行时间
if (index >= size / 2) {
//index超过一半,所以从尾部更快
currentNode = currentNode.prev;
for (int i = 0; i < size-index ; i++) {
currentNode = currentNode.prev;
}
}else{
//从头部开始
currentNode = currentNode.next;
for (int i = 0; i < index ; i++){
currentNode = currentNode.next;
}
}
return currentNode.val;
}
public void addAtHead(int val) {
int index = 0;
addAtIndex(index,val);
}
public void addAtTail(int val) {
//这里是需要index等于size还是index等于size减一呢?
//因为是从0开始的,所以下标是到size--,末尾的加一个节点的下标就是size
int index = size;
addAtIndex(index,val);
}
public void addAtIndex(int index, int val) {
//index的判断
if(index > size){
return;
}
if (index < 0) {
index = 0;
}
size++; //长度增加
//找到插入节点的前驱
ListNode pre = head;
for(int i = 0; i < index; i++){
pre = pre.next;
}
//新建的节点
ListNode addNode = new ListNode(val);
addNode.next = pre.next;
pre.next.prev = addNode;
addNode.prev = pre;
pre.next = addNode;
}
public void deleteAtIndex(int index) {
//index的判断
if(index < 0 || index >= size){
return;
}
size--; //长度减少
//找到链表的前驱
ListNode pre = head;
for(int i = 0; i < index; i++){
pre = pre.next;
}
pre.next = pre.next.next;
pre.next.next.prev = pre;
}
}