单向链表的概要以及常规方法
单向链表由三部分组成
-
单个的节点
-
将节点穿起来的链表
-
放入链表里的数据
import javax.xml.soap.Node;
/**
* @author YanAemons
* @date 2021/10/3 17:36
*/
public class NodeC {
int data;
int np;
String names;
NodeC next;
public NodeC(int data, int np, String names)
{
this.np = np;
this.names = names;
this.data = data;
this.next = null;
}
}
节点
每个节点相当于一个带有方向的容器(也可理解为向量吧),在容器内部放置数据, 该容器还包含一个带有方向的属性(类似指针)指向下一个节点,以达到将各个节点连接起来组成单向链表,并以此类推
链表
/**
* @author YanAemons
* @date 2021/10/3 17:40
*/
public class LinkedList {
private NodeC first;
private NodeC last;
public boolean isEmpty()
{
return first == null;
}
public void print()
{
NodeC current = first;
while (current != null)
{
System.out.println("["+current.data+" "+current.names+" " +current.np+"]");
current = current.next;
}
System.out.println(" ");
}
public void insert(int data, String names, int np)
{
NodeC newNode = new NodeC(data, np, names);
if (this.isEmpty())
{
first = newNode;
last = newNode;
}
else
{
last.next = newNode;
last = newNode;
}
}
}
链表由一个一个节点组成,链表内将设置其对节点的操作(如增删改查等),该类包含两个基本属性头指针和尾指针(这同样也是两个节点,只不过在链表中扮演指针的角色),其他方法将通过控制这两个指针来对节点进行操作。如上文的insert()方法采用了工厂模式来创建新的节点并修改尾指针来将新节点加入链表中,该例insert()方法也定义了容器中的数据包含了哪些内容(data, np, names)
链表的使用
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author YanAemons
* @date 2021/10/3 17:58
*/
public class StudentLink {
public static void main(String[] args) throws IOException {
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
int num;
String name;
int score;
System.out.println("请输入5个学生数据: ");
LinkedList list = new LinkedList();
for (int i = 1; i < 6; i++)
{
System.out.println("输入学号:");
num = Integer.parseInt(buf.readLine());
System.out.println("请输入姓名:");
name = buf.readLine();
System.out.println("请输入成绩:");
score = Integer.parseInt(buf.readLine());
list.insert(num, name, score);
System.out.println("-----------");
}
System.out.println("学生成绩");
System.out.println("学号成绩============");
list.print();
}
}
删除列表后的节点
将删除节点的前一个节点的指针,指向欲删除节点的下一个节点
newNode = first;
tmp = first;
while(newNode.data != delNode.data)
{ // 将头指针移动到要删除的前一个节点
tmp = newNode;
newNode = newNode.next
}
tmp.next = delNode.next;
在该示例中节点tmp和newNode同样扮演的两个指针,newNode指针的作用是通过while循环来根据链表方向定位需要删除的节点的位置,而tmp指针始终在newNode指针的上一个节点,这样当newNode指针找到需要删除节点的位置是,tmp指针便定位到delNode节点的前一个节点,更改delNode的前一个节点的指向(也就是跳过delNode节点)便实现了删除delNode节点
删除最后一个节点
只要将指向最后一个节点的指针,直接指向null即可
if(last.data == delNode.data)
{
newNode = first;
while(newNode.next != last) newNode = newNode.next;
newNode.next = last.next;
last = newNode;
}
该示例中,指针newNode通过循环定位到最后一个节点的前一个节点,并修改last指针
插入与删除的实现类似
在列表的第一节插入节点
只需把新节点的指正指向表头,再把表头一到新节点上即可
最后插入
吧列表的最后一个节点的指针指向新节点,新节点在指向null
在列表中间插入
如果插入的节点在X与Y之间,只需要将X的节点的指针指向新节点,新节点指针指向Y节点即可
单向链表的反转
public void reverse_print()
{
Node current = first;
Node before = null;
while(current != null)
{
last = before;
before = current;
current = current.next;
before.next = last;
}
current = before;
}