1.链表的头插
2.链表的尾插
3.在链表中任意位置前插入
4.查找链表中是否有某一个值val
5.删除第一次出现的值key
6.删除所有出现的值key
在实现链表的功能前,我们首先要明白链表是由每一个结点构成的,每一个结点其实就是一个类,是由val值域和next域构成的,所以我们要先构造一个结点类,即静态内部类


java
public LinkedList {
//创建结点
static class ListNode{
//每个结点都有val值域和next结点域组成
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
}
让后我们手动创建一个链表,然后让每一个结点next指向下一个结点的

1.链表的头插
在进行头插的时候,我们需要判断这个链表是否为空,如果链表为空的话,那么链表的head就是要插入的新结点,这个需要我们注意

java
public void addFirst(int val) {
//申请新的结点
ListNode newNode = new ListNode(val);
//判断链表是否为空,如果链表为空,那么要插入的结点就是head
if(head == null) {
head = newNode;
return;
}
//否则就进行头插
newNode.next = head;
head = newNode;
}

2.链表的尾插
链表的尾插,只需要判断这个链表是否为空,如果为空,那么就相当于头插,如果不为空,那么就只需要我们找到链表的最后一个结点即可

java
public void addLast(int val) {
ListNode newNode = new ListNode(val);
if(head == null) {
head = newNode;
return;
}
//如果链表不为空,那么就要找到最后一个结点
//定义cur去查找最后一个结点,不要用head去找,不然找完后head就不指向第一个结点了
ListNode cur = head;
while(cur.next != null) {
cur = cur.next;
}
cur.next = newNode;
}

3.在链表中任意位置前插入
在任意位置插入的时候,如果插入的位置为0或者为size,那么就是头插或者尾插,插入前要判断插入的位置是否合法,如果插入的位置<0或者>size,那么插入失败,否则就要找到插入的结点的前一个结点

java
public void addIndext(int pos, int val) {
ListNode newNode = new ListNode(val);
if(pos < 0 || pos > size()) {
System.out.println("插入位置非法!!!,程序退出");
return;
}
if(pos == 0) {
//头插
addFirst(val);
return;
} else if(pos == size()) {
//尾插
addLast(val);
return;
}
//找到要插入的结点的前一个结点
ListNode cur = head;
for(int i = 1; i < pos; i++) {
cur = cur.next;
}
//出了循环,cur就在要插入的结点的前面
newNode.next = cur.next;
cur.next = newNode;
}

4.查找链表中是否有某一个值val

java
public boolean contains(int key) {
ListNode cur = head;
while(cur != null) {
if(cur.val == key) {
System.out.println("查找成功");
return true;
}
cur = cur.next;
}
System.out.println("查找失败");
return false;
}
5.删除第一次出现的值key
首先先判断链表是否为空,如果不为空,则先判断头结点是不是就是val,如果是,那么让头结点向后走即可,如果不是,那么遍历一次链表看是否能找到,如果找不到则说明这个链表没有这个val值

java
public void remove(int key) {
ListNode cur = head;
//判断链表是否为空
if(head == null) {
System.out.println("链表为空,无此关键字");
return;
}
if(cur.val == key) {
head = head.next;
return;
}
while(cur.next != null) {
if(cur.next.val == key) {
cur.next = cur.next.next;
System.out.println("删除成功");
return;
}
cur = cur.next;
}
System.out.println("此链表无此关键字key->" + key);
}
6.删除所有出现的值key

java
public void removeAllKey(int key) {
ListNode cur = head.next;
ListNode prev = head;
if(cur == null) {
System.out.println("链表为空,程序退出");
return;
}
while(cur != null) {
if(cur.val == key) {
prev.next = cur.next;
cur = cur.next;
}else {
prev = prev.next;
cur = cur.next;
}
}
//最后判断一下头结点是否为val值
if(head.val == key) {
head = head.next;
}
}
总结:
在创建链表的时候,我们要清楚链表是由一个个结点构成的,而每一个结点都是由val域和next域构成,所以我们可以将结点看成一个类,然后在模拟实现方法的时候,我们都要先判断这个链表是否为空,而顺序表是判断是否为满。