在计算机科学中,链表是数据元素的线性集合,其每个元素都指向下一个元素,元素存储上并不连续。其代码如下:
private Node head=null; //定义头指针
//定义节点
private static class Node {
int value; //设置值
Node next; //设置指向下一个节点的指针
public Node(int value, Node next) {
this.value = value;
this.next = next;
}
}
图7-1
首先定义一个头指针,设置值,和指向下一节点的指针,如图7-1所示。
图7-2
在头部插入,只需新节点指向原始原节点指向的节点,头节点指向新插入的节点即可,如图7-2所示。
图7-3
在尾部插入,需要找到最后一个节点4,让该节点指向新插入的节点,新节点的下一个节点为空,如图7-3所示。
图7-4
根据指定的索引插入需要找到待插入索引的前一个值,如果索引为0,即是在头部插入,如果要在索引为1的位置插入,需要查找前一个索引0的位置,使该节点指向插入的新节点,新节点指向索引为0指向的节点,如图7-4所示。
图7-5
删除第一个元素,只需让头节点指向指向头节点指向的另一个元素,如图7-5所示。
图7-6
根据索引删除同样需要找点待删除索引的前一个索引,让前一个索引的节点指向待删除的节点的下一个节点即可,如图7-6所示。
完整代码如下:
public class SingleLinkedList {
//测试在头部插入
@Test
public void testAddFirst(){
addFirstValue(1);
addFirstValue(2);
addFirstValue(3);
addFirstValue(4);
addFirstValue(5);
loopLinked(); // 4 3 2 1
}
//测试在尾部插入
@Test
public void testAddLast(){
addLastValue(1);
addLastValue(2);
addLastValue(3);
addLastValue(4);
addLastValue(5);
loopLinked();// 1 2 3 4
}
//测试根据索引查找对应的值
@Test
public void testGetValue(){
addLastValue(1);
addLastValue(2);
addLastValue(3);
addLastValue(4);
System.out.println(getValue(2)); //3
}
//测试指定索引查找对应的值并插入
@Test
public void testInsert(){
addLastValue(1);
addLastValue(2);
addLastValue(3);
addLastValue(4);
insertValue(1,5);
loopLinked();
}
//测试删除
@Test
public void testRemove(){
addLastValue(1);
addLastValue(2);
addLastValue(3);
addLastValue(4);
removeFirst();
removeIndex(1);
loopLinked();
}
private Node head=null; //定义头指针
//定义节点
private static class Node {
int value; //设置值
Node next; //设置指向下一个节点的指针
public Node(int value, Node next) {
this.value = value;
this.next = next;
}
}
//在头部插入值
public void addFirstValue(int value){
//添加值
head=new Node(value,head);
}
//查找最后一个
public Node findLast(){
if (head==null){
return null;
}
Node pointer;
for(pointer=head;pointer.next!=null;pointer=pointer.next){
}
return pointer;
}
//在尾部插入
public void addLastValue(int value){
//如果链表为空,只需要在头部插入
Node last = findLast();
if (last==null){
addFirstValue(value);
return;
}
last.next=new Node(value,null);
}
//根据索引找到节点
public Node findNode(int index){
int i=0;
for (Node pointer=head;pointer.next!=null;pointer=pointer.next,i++){
if (index==i){
return pointer;
}
}
return null;
}
//查找值
public int getValue(int index){
Node node = findNode(index);
if (node==null){
throw new IllegalArgumentException("参数不合法:"+index);
}
return node.value;
}
//像指定位置插入
public void insertValue(int index,int value){
//索引为0,即在头部插入
if (index==0){
addFirstValue(value);
return;
}
//找到待插入索引的前一个节点
Node preNode = findNode(index - 1);
if (preNode==null){
throw new IllegalArgumentException("参数不合法:"+index);
}
//创造新节点指向下一个节点,前一个节点指向新节点
preNode.next=new Node(value,preNode.next);
}
//删除第一个元素
public void removeFirst(){
//只需头指点指向下一个
head=head.next;
}
//根据索引删除
public void removeIndex(int index){
//如果index==0相当于在头部删除
if (index==0){
removeFirst();
}
//找到删除的上一个索引
Node prevNode = findNode(index - 1);
//判断是否为空
if (prevNode==null){
throw new IllegalArgumentException("参数不合法:"+index);
}
Node remove = prevNode.next;
//判断要删除的是否为空
if (remove==null){
throw new IllegalArgumentException("参数不合法:"+index);
}
prevNode.next=remove.next;
}
//遍历链表
public void loopLinked(){
//定义一个初始指针指向第一个值
Node pointer=head;
//循环遍历元素,只要指针不为空,就有元素
while (pointer!=null){
System.out.println(pointer.value);
pointer=pointer.next;
}
}
}