**Java链表的增删改查**
1.首先得创建一个链表,代码如下:
class Node{
public int val;
public Node next;
public Node(){
//无参构造方法
}
public Node(int val){
this.val=val;
}
}创建Node结点
public class MyLinkList {
public Node head;
// 1、无头单向非循环链表实现
public void creatLinkList(){
this.head=new Node(1);
Node node1=new Node(2);
Node node2=new Node(3);
Node node3=new Node(4);
this.head.next=node1;
node1.next=node2;
node2.next=node3;
}
}引用并连接结点构成链表
如图:
创建头结点head,必须有头才能找到尾,然后创建node1,node2,node3,让头结点的next存储node1,这样通过调用this.head就可以找到node1,用this.head…next.val就可以找到node1中的值val,其余结点使用方法相同;
Node的含义是一个结点,这个结点中包含了val和next,val中包含的是该结点中存储的值,next存储的是下一个结点的地址,对于一个链表来讲,找到下一个值也就是找next引用的结点,在这个结点中通过val就可以找到这个值。
2.接下来就要使用链表了,首先打印链表,打印链表就得从头开始打印,所以打印方法要先定义一个头结点,然后遍历链表。如图
public void display(){
Node cur=new Node();
cur=this.head;
while (cur!=null){
System.out.print(cur.val+" ");
cur=cur.next;
}
}
该方法定义了一个新结点让他指向头结点,只要该结点不为空,说明结点里存储有值,就打印一次,然后cur向后走一步,即cur.next作为一个新的头;
3.接下来就是对链表进行增删改查了,首先是增加链表长度,这里有三种方法,分别为头插法,尾插法和给定位置插入
首先头插法,顾名思义就是插入一个元素作为链表的新头,代码如下
public void addFirst(int data){
Node node=new Node(data);
node.next=this.head;
this.head=node;
}
其实就是给了一个数据data,创建一个新的结点node,而node中的val值就是data,让node.next存储头结点的引用就完成了头插数据
有了头插法我们就可以很轻松的完成尾插法,代码如下
public void addLast(int data){
Node node=new Node(data);
Node cur=this.head;
if(this.head==null){
addFirst(data);
}else{
while (cur.next!=null){
cur=cur.next;
}
cur.next=node;
}
}
可见尾插法与头插法不同的是尾插法需要遍历到链表最后一个元素,最后一个元素的引用是null,将null替换成插入节点的引用,就完成了尾插法
中间任意位置插入其实就是把插入元素的头换成上一个元素的尾,把插入元素的尾换成下一个元素的头,这样就连接起了整个链表并完成了数据插入,如下
public boolean addIndex(int index,int data){
Node node=new Node(data);
Node cur=this.head;
if(index==0){
addFirst(data);
return true;
}else if(index==size()){
addLast(data);
return true;
}
if(index<0||index>size()){
System.out.println("插入位置不合法");
return false;
}
else{
for (int i = 0; i <index-1 ; i++) {
cur=cur.next;
}
node.next=cur.next;
cur.next=node;
}
return true;
}
这里稍稍复杂了一点,因为可能面临判空等空指针异常等情况所以多了一些判断
最核心的代码是这两句
node.next=cur.next;//插入节点的尾指向下一个结点的头
cur.next=node;//链表插入位置元素的下一个结点指向插入元素的头
4.链表的删除,我们知道了链表的增加,对于删除道理也是一样的,将删除元素的头换成删除元素的尾,那么遍历链表的时候就不会出现被删除的元素,就完成了元素的删除,如下
//删除第一次出现关键字为key的节点
public void remove(int key){
Node cur=this.head;
if(cur==null){
System.out.println("链表为空,删除错误");
return;
}else if(cur.val==key&&cur.next==null){
this.head=null;
return;
}else if(this.head.val!=key&&cur.next==null){
System.out.println("未找到key");
return;
}else if(this.head.val==key){
this.head=this.head.next;
return;
}
while (cur.next!=null){
if(cur.next.val==key){
cur.next=cur.next.next;
return;
}
cur=cur.next;
}
System.out.println("未找到key");
}
// 删除所有值为key的节点
public void removeAllKey(int key){
Node cur=this.head;
if(cur==null){
System.out.println("链表为空,删除错误");
}else if(cur.next==null&&cur.val==key){
this.head=null;
}else if(cur.next==null&&this.head.val!=key){
System.out.println("未找到key");
}else if(cur.val==key){
this.head=this.head.next;
}
while (cur.next!=null){
if(cur.next.val==key){
cur.next=cur.next.next;
continue;
}
cur=cur.next;
}
}
这里分别写了删除第一次出现该值的结点和所有出现该值的结点
其次就是一些链表的清除和其他操作不再详述;
链表的清除,只要让头结点指向null就让链表清空了;
链表的基本用法就是这些,可能还有没提到的,老铁评论区留言提醒一下