链表的基本操作
与顺序表相同,链表也有增、删、改、查等操作
下面用代码演示:
首先定义一个结点的类,和构造方法
class Node {
public int value;
public Node next;
public Node (int value) {
this.value = value;
this.next = null;
}
}
创建一个链表
public static Node createLinkedList() {
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = null;
return n1;
}
增操作即插入,可分为头插尾插
头插:
//头插
public static Node pushFront(Node head, int value) {
//1.申请新结点
Node newnode = new Node(value);
//2.更新newnode的next
newnode.next = head;
//3.更新head
return newnode;
}
尾插:
尾插要考虑一些特殊情况
//尾插
public static Node pushBack(Node head, int value) {
Node newnode = new Node(value);
//链表为空
if(head == null){
return pushFront(head, value); // newnode.next = head; return newnode ;
}else {
Node last = getLast(head);
last.next = newnode;
return head;
}
}
//帮助尾插找到尾节点的方法
//找到尾节点
public static Node getLast(Node head) {
Node cur = head;
while(cur.next != null){
cur = cur.next;
}
return cur;
}
删除操作
删除操作也可分为头删尾删
头删:
//头删
public static Node popFront(Node head) {
if(head == null) {
System.out.printf("空链表结点无法删除");
return null;
}
return head.next;
}
尾删:
尾删也要考虑一些特殊的情况
//尾删
public static Node popBack(Node head) {
if(head == null) {
System.out.printf("空链表结点无法删除");
return null;
}
if(head.next == null) {
//链表只有一个结点
//视为头删
return null;
}else {
// 1. 找倒数第二个结点
Node lastLast = getLastLast(head);
// 2. 让倒数第二个结点的 next = null
lastLast.next = null;
// 3. 释放原最后一个结点
return head;
}
}
//帮助尾删找到倒数第二个结点的方法
//找倒数第二个结点
private static Node getLastLast(Node head) {
Node node = head;
while (node.next.next != null) {
node = node.next;
}
return node;
}
给定一个值删除:
可以分几种方法
一:遍历找到要删除的值,删除该结点
//遍历每个结点,如果结点值为要删除的值,删除该节点
public static Node removeElements(Node head, int value) {
if(head == null) {
return null;
}
Node cur = head.next;
Node pre = head;
while(cur != null) {
if(cur.value == value) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
if(head.value == value) {
head = head.next;
}
return head;
}
二:遍历将不为要删除的值的结点尾插到一个新的链表
//遍历每个结点,如果结点值不为要删除的值,则将该节点尾插入一个新的链表
public static Node removeElements2(Node head, int value) {
Node newList = null;
Node last = null;
Node cur = head;
while(cur != null) {
Node next = cur.next;
if(cur.value != value) {
//尾插到newList
if(newList == null) {
cur.next = newList;
newList = cur;
}else {
last.next = cur;
}
last = cur;
}
cur = next;
}
return newList;
}
其他的操作
转换链表顺序
//转换链表顺序
//一.遍历链表并将结点按遍历顺序头插入一个新的链表
public static Node reverseList(Node head){
Node newList = null;
Node cur = head;
while(cur != null) {
Node next = cur.next;
cur.next = newList;
newList = cur;
cur = next;
}
return newList;
}
实现这些方法
public static void main(String[] args) {
Node head = createLinkedList();
display(head);
head = removeElements2(head,4);
display(head);
head = null;
display(head);
head = pushBack(head,1);
head = pushBack(head,2);
head = pushBack(head,3);
display(head);
head = pushFront(head,10);
head = pushFront(head,20);
head = pushFront(head,30);
display(head);
head = popFront(head);
head = popFront(head);
head = popFront(head);
display(head);
/*head = popBack(head);
display(head);*/
head = reverseList(head);
display(head);
head = removeElements(head,2);
display(head);
}
输出链表
//print
public static void display(Node head) {
Node cur = head;
while(cur != null){
System.out.printf("(%d)-->",cur.value);
cur = cur.next;
}
System.out.printf("null%n");
}
结果: