链表(Java)一
力扣第707:设计链表
额外注意:假设链表中的所有节点都是 0-index 的(当时我没注意到这个,就被坑了)咱们是有头结点的,但是头结点不算在内,所以咱们循环的时候就要比输入的index少循环一次这也就是添加和删除在for循环的时候,咱们可以顺利找到位置为index的节点的前一个节点的原因,但是在查找的时候咱们要记得加一,才能找到目标节点
咱们可以设计一个单链表或者双向链表来解这个题目,所以咱们写了一个接口,方便大家知道有哪些需要实现的方法
/**
* @program: testspring
* @description: 链表的接口
* @author: ErFeng_V
* @create: 2021-04-18 09:31
*/
public interface MyLinkedList {
/**
*在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
* @param val
*/
public void addAtHead(int val) ;
/**
* 将值为 val 的节点追加到链表的最后一个元素
* @param val
*/
public void addAtTail(int val);
/**
* 获取链表中第 index 个节点的值。如果索引无效,则返回-1。
* @param index
* @return
*/
public int get(int index);
/**
* 在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,
* 则该节点将附加到链表的末尾。如果 index 大于链表长度,
* 则不会插入节点。如果index小于0,则在头部插入节点。
* @param index
* @param val
*/
public void addAtIndex(int index, int val);
/**
* 如果索引 index 有效,则删除链表中的第 index 个节点。
* @param index
*/
public void deleteAtIndex(int index);
}
单链表
单链表是一个链式存储结构,像下面这样
单链表首先咱们定义一个节点类,如下:
class ListNode{
int val;
//指向下一个节点
ListNode next;
public ListNode(){};
public ListNode(int val){
this.val =val;
}
}
咱们可以首先来实现get(int index)这个方法,如下:
public int get(int index) {
ListNode p=head;
for(int i=0;i<index+1;i++){
p=p.next;
}
return p.val;
}
接下来咱们来实现题目中的addAtIndex(int index, int val)这个方法
首先咱们通过for循环找到要插入位置节点的前一个节点,咱们叫它点p
然后咱们new一个节点m,并将m的下一个节点指向p的下一个节点
最后一步,也是重要的一步,将p的下一个节点指向咱们的节点m
这样,咱们的添加就算完成了
代码如下
public void addAtIndex(int index, int val) {
//如果index大于链表长度,则不会插入节点
if(index>this.size) {
return;
}else //如果index小于0,则在头部插入节点。
if(index<0 && this.size>0){
index=0;
}
//图解的核心在这
ListNode p=head;
for(int i=0;i<index;i++){
p=p.next;
}
ListNode m=new ListNode(val);
m.next=p.next;
p.next=m;
size++;
}
下面咱们来实现删除操作
首先咱们依旧来找到节点p
然后把p的下一个节点指向p的下一个节点的节点,如图
删除的代码如下
public void deleteAtIndex(int index) {
if(index>this.size || index<0){
return;
}
ListNode p=head;
for(int i=0;i<index;i++){
p=p.next;
}
//图解核心在这
p.next=p.next.next;
size--;
}
至此咱们的添加和删除就完成啦
剩下还有两个addAHead和addAtTail这两个方法,大家可以自己尝试一下哈,加油!
单链表的完整代码如下
/**
* @program: testspring
* @description: 单链表 假设链表中的所有节点都是 0-index 的
* @author: ErFeng_V
* @create: 2021-04-18 09:43
*/
public class SinglyLinkedList implements MyLinkedList {
private int size;
private ListNode head;
public SinglyLinkedList(){
this.size=0;
//头结点初始化
this.head=new ListNode(0);
}
@Override
public void addAtIndex(int index, int val) {
//如果index大于链表长度,则不会插入节点
if(index>this.size) {
return;
}else //如果index小于0,则在头部插入节点。
if(index<0 && this.size>0){
index=0;
}
ListNode p=head;
for(int i=0;i<index;i++){
p=p.next;
}
//如果 index 等于链表的长度,则该节点将附加到链表的末尾
ListNode m=new ListNode(val);
m.next=p.next;
p.next=m;
size++;
}
@Override
public void deleteAtIndex(int index) {
if(index>this.size || index<0){
return;
}
ListNode p=head;
for(int i=0;i<index;i++){
p=p.next;
}
p.next=p.next.next;
size--;
}
@Override
public void addAtHead(int e) {
addAtIndex(-1,e);
}
@Override
public void addAtTail(int e) {
addAtIndex(size,e);
}
@Override
public int get(int index) {
ListNode p=head;
for(int i=0;i<index+1;i++){
p=p.next;
}
return p.val;
}
}
class ListNode{
int val;
ListNode next;
public ListNode(){};
public ListNode(int val){
this.val =val;
}
}