原来链表这么用
本关卡主要描述了链表的基本概念,以及如何实现单链表,对其数据进行增删改查的操作。
单链表的概念:
链表,通过链表存储数据,不强制要求数据在内存中集中存储,各个元素可以分散的存储在内存中。
其元素之间相互连接,包含多个结点,每个结点有一个指向后继元素的next指针。最后一个元素的next指向为null
形如:
单链表的相关概念:
节点和头节点
在链表中,每个点都是由值和指向下一个结点的地址组成的独立单元,称为一个结点(节点)。
第一个节点,成为头节点。通过该节点,可以遍历整个链表。
虚拟节点
方便我们处理首部节点。注意头个元素应为dummyNode.next
创建单链表
public class ListNode {
private int data;
private ListNode next;
public ListNode(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode next) {
this.next = next;
}
}
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
next = null;
}
public static void main(String[] args) {
ListNode listnode=new ListNode(1);
}
}
单链表的增删改查
遍历单链表
public static int getListLength(Node head) {
int length = 0;
Node node = head;
while (node != null) {
length++;
node = node.next;
}
return length;
}
单链表的插入
头部插入元素
表头插入元素要注意head的指向
尾部插入元素
中间插入元素
单链表的元素删除
代码实现上述增删改查
public class BasicLinkList {
static class Node {
final int data;
Node next;
public Node(int data) {
this.data = data;
}
}
public static void main(String[] args) {
// 头部添加节点1
Node head = new Node(1);
System.out.println("头部添加节点1:" + BasicLinkList.toString(head));
System.out.println("链表长度为:" + getLength(head));
// 尾部添加节点2
Node node = new Node(2);
head = BasicLinkList.insertNode(head, node, 2);
System.out.println("尾部添加节点2:" + BasicLinkList.toString(head));
System.out.println("链表长度为:" + getLength(head));
// 中间添加节点3
node = new Node(3);
head = BasicLinkList.insertNode(head, node, 2);
System.out.println("中间添加节点3:" + BasicLinkList.toString(head));
// 删除中间节点2
head = BasicLinkList.deleteNode(head, 2);
System.out.println("删除中间节点3:" + BasicLinkList.toString(head));
// 删除头部节点1
head = BasicLinkList.deleteNode(head, 1);
System.out.println("删除头部节点1:" + BasicLinkList.toString(head));
// 再删
head = BasicLinkList.deleteNode(head, 1);
System.out.println("删除头部节点:" + BasicLinkList.toString(head));
}
/**
* 获取链表长度
*
* @param head 链表头节点
* @return 链表长度
*/
public static int getLength(Node head) {
int length = 0;
Node node = head;
while (node != null) {
length++;
node = node.next;
}
return length;
}
/**
* 链表插入
*
* @param head 链表头节点
* @param nodeInsert 待插入节点
* @param position 待插入位置,取值从2开始
* @return 插入后得到的链表头节点
*/
public static Node insertNode(Node head, Node nodeInsert, int position) {
// 先要注意参数异常的情况
// 传入的头结点为null;参数传递的position的位置越界
if(head==null) {
// 待插入的结点head就是链表的头结点,也可以抛出不能插入的异常
System.out.println("传入的结点为null");
return nodeInsert;
}
int len=getLength(head);
if(position<1 ||position>len+1) {
System.out.println("待插入的位置越界");
return head;
}
// 特殊处理
// 表头插入
if(position==1){
nodeInsert.next=head;
head=nodeInsert;
return head;
}
// 其他
Node pNode=head;
int count=1;
while (count++<position-1){
pNode = pNode.next;
}
nodeInsert.next=pNode.next;
pNode.next=nodeInsert;
return head;
}
/**
* 删除节点
*
* @param head 链表头节点
* @param position 删除节点位置,取值从1开始
* @return 删除后的链表头节点
*/
public static Node deleteNode(Node head, int position) {
// 删除头部元素,删除中间元素和删除尾部元素。
if(head==null){
return null;
}
int len=getLength(head);
if(position>len || position<1){
System.out.println("输入的位置参数有误");
return head;
}
// 删除头结点
if(position==1) {
return head.next;
}else{
Node cur=head;
int count=1;
while (count++<position-1){
cur=cur.next;
}
/* Node curNode=cur.next;
cur.next=curNode.next; */
cur.next=cur.next.next;
}
return head;
}
/**
* 输出链表
*
* @param head 头节点
*/
public static String toString(Node head) {
Node current = head;
StringBuilder sb = new StringBuilder();
while (current != null) {
sb.append(current.data).append(" ");
current = current.next;
}
return sb.toString();
}
}