Java实例04-实现一个可进行增删查改的单向链表
Node节点类:
public class Node {
//为了不让外部类使用Node类,使用private修饰data和next
/**
* 节点储存的数据
*/
private Object data;
/**
* 节点存储的指向下一个节点的地址,默认为null
*/
private Node next;
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
主类:
public class LinkedListDemo01 {
//定义头节点
private Node head;
//定义链表长度
private int size = 0;
/**
* 1.1从链表头部添加节点
*/
public void addHead(Object data) {
//创建新节点
Node newNode = new Node(data,null);
//当链表不为空时,使新节点指向旧的头节点
if (head != null) {
newNode.setNext(head);
}
//使新节点成为新的头节点
head = newNode;
//链表长度加1
size++;
}
/**
* 1.2从链表尾部添加节点
*/
public void addEnd(Object data) {
//创建新节点
Node newNode = new Node(data,null);
if (head == null) {
//当链表为空时,使新节点成为头节点
head = newNode;
} else {
//当链表不为空时,找到当前链表的末节点,使其指向新节点,新节点成为新的末节点
getEnd(head).setNext(newNode);
}
//链表长度加1
size++;
}
/**
* 1.3在指定位置插入新节点,
*/
public void add(int index,Object data){
rangeCheck(index);
Node newNode = new Node(data,null);
//先将新节点指向目标位置的原节点
newNode.setNext(getNode(index));
//再将目标节点的前一个节点指向新节点
getNode(index - 1).setNext(newNode);
size++;
}
/**
* 2.通过下标删除节点
*/
public void delete(int index) {
//判断链表中是否有数据
if (size > 0) {
//检查下标是否越界
rangeCheck(index);
//将目标节点赋给一个临时节点
Node tempNode = getNode(index);
//当链表中只有一个节点时
if (size == 1) {
head = null;
} else {
//当目标节点是头节点时
if (tempNode == head) {
head = tempNode.getNext();
}
//使目标节点的前一个节点指向目标节点的后一个结点
getNode(index - 1).setNext(tempNode.getNext());
}
//链表长度减一
size--;
}
}
/**
* 3.1通过值找到目标节点
*/
public Node getNode(Object value) {
Node tempNode = head;
while (tempNode != null) {
if (tempNode.equals(value)) {
return tempNode;
}
tempNode = tempNode.getNext();
}
//如果没有找到,返回null
return null;
}
/**
* 3.2通过下标找到目标节点
*/
public Node getNode(int index) {
rangeCheck(index);
Node tempNode = head;
for (int i = 0; i < index; i++) {
tempNode = tempNode.getNext();
}
return tempNode;
}
/**
* 3.3找到尾节点
*/
public Node getEnd(Node node) {
if (node.getNext() == null) {
return node;
}
//使用递归
return getEnd(node.getNext());
}
/**
* 4.更改目标节点的值
*/
public void update(int index, Object newData) {
//首先根据值找到目标节点,然后将新的值赋给它
getNode(index).setData(newData);
}
/**
* 5.size返回链表长度
*/
public int size() {
return size;
}
//6.isEmpty
public boolean isEmpty() {
return size() == 0;
}
/**
* 7.显示所有节点信息
*/
public void print() {
Node tempNode = head;
while (tempNode != null) {
System.out.println(tempNode.getData());
tempNode = tempNode.getNext();
}
}
//8.下标越界抛出异常
private void rangeCheck(int index) {
if (index < 0 || index > this.size()) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size();
}
}
测试类:
public class LinkedListTest01 {
public static void main(String[] args) {
LinkedListDemo01 link = new LinkedListDemo01();
System.out.println("此时链表是否为空? " + link.isEmpty());
link.addEnd("AA");
link.addEnd("bb");
link.addEnd("CC");
link.addEnd("DD");
System.out.println("---------添加后---------");
link.print();
System.out.println("此时链表是否为空? " + link.isEmpty());
link.add(1,"FFF");
System.out.println("---------插入后---------");
link.print();
link.update(2,"BB");
System.out.println("---------变更后---------");
link.print();
link.delete(1);
System.out.println("---------删除后---------");
link.print();
}
}
结果:
此时链表是否为空? true
---------添加后---------
AA
bb
CC
DD
此时链表是否为空? false
---------插入后---------
AA
FFF
bb
CC
DD
---------变更后---------
AA
FFF
BB
CC
DD
---------删除后---------
AA
BB
CC
DD