链表的常见操作实现(删除,插入,增加,查询)
public class LinkedList {
/**
* 初始节点
*/
private Node fristNode;
/**
* 末尾节点
*/
private Node lastNode;
/**
* 节点的个数
*/
private int size;
/**
* 获得节点的个数
*
* @return
*/
public int size() {
return size;
}
class Node {
/**
* 节点的末尾位置
*/
/**
* 指向上一个节点
*/
private Node prev;
/**
* 节点存储的数据
*/
private String data;
/**
* 指向下一个节点
*/
private Node next;
/**
* 无参构造方法
*/
public Node() {}
/**
* 有参构造方法
* @param prev
* @param data
* @param next
*/
public Node(Node prev, String data, Node next) {
this.prev = prev;
this.data = data;
this.next = next;
}
}
/**
* 链表结构实现添加元素操作
*
* @param element
* 需要添加的元素 ,数据类型为String.
*/
public void add(String element) {
if (fristNode == null) {// ,节点为空的情况,创建一个节点。
Node node = new Node(null, element, null);
// 将首节点和尾节点设置为node(因为节点的创建要么是首节带,要么是尾节点)
fristNode = node;
lastNode = node;
// 节点的个数自增
size++;
} else {// 节点不为空的情况,在尾节点的末尾添加一个节点。
Node node = new Node(null, element, null);
// 让尾节点的末尾位置指向要添加的新节点node。
lastNode.next = node;
// 让新节点node的首位置指向尾节点。
node.prev = lastNode;
// 添加成功,新创建的新节点node设置为尾节点。
lastNode = node;
// 节点的个数自增
size++;
}
}
/**
* 链表遍历数据操作
*
* @param index
* 传入的索引
*/
public String get(int index) {
if (index < 0 || index >= size) {// 判断索引输入是否合法。
throw new IndexOutOfBoundsException("输入的索引有误。" + index);
}
Node node = node(index);
return node.data;
}
/**
* 根据输入的索引,获取对应的节点
*
* @param index
* 输入的索引
* @return 对应的节点
*/
public Node node(int index) {
// 索引合法的情况下,判断索引的位置,优化遍历方法。
// 从前往后找
if (index < size >> 1) {
// 声明一个初始节点
Node node = fristNode;
for (int i = 0; i < index; i++) {
// 通过循环,遍历节点中的数据
node = node.next;
}
return node;
} else {
Node node = lastNode;// 声明一个末节点
// 从后往前找
for (int i = size - 1; i > index; i--) {
node = node.prev;
}
return node;
}
}
/**
* 链表的删除操作
*
* @param index
* 输入对应的索引
*/
public void remove(int index) {
// 1.判断索引是否合法
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException("索引越界异常:" + index);
}
// 2.获取index对应的节点对象
Node node = node(index);
if(node==fristNode){
fristNode = node.next;
fristNode.prev=null;
}
else if(node==lastNode){
lastNode=node.prev;
lastNode.next=null;
}
else{
// 3.获取node节点的上一个节点和下一个节点
Node prevNode = node.prev;
Node nextNode = node.next;
// 4.更改prevNode和nextNode的指向关系
prevNode.next = nextNode;
nextNode.prev = prevNode;
// 5.更新size实际存放元素的个数
size--;
}
}
/**
* 根据索引插入元素
* @param element 插入的元素
* @param index 插入位置的索引
*/
public void add(String element, int index) {
// 1.判断索引是否合法
if(index < 0 || index > size) {
throw new IndexOutOfBoundsException("索引越界异常:" + index);
}
// 2.判断插入的元素是否在链表的末尾
if(index == size) {
add(element);
}
// 3.判断插入的元素是否在链表的开头
else if(index == 0){
// 3.1把需要插入的元素包装为一个节点
Node node = new Node(null, element, null);
// 3.2更改firstNode和node之间的连线
fristNode.prev = node;
node.next = fristNode;
// 3.3更新链表的首节点
fristNode = node;
// 3.4更新size实际存放元素的个数
size++;
}
// 4.把index插入指定的位置(排除末尾和开头)
else {
// 4.1获取index对应的元素节点
Node nextNode = node(index);
// 4.2获取index对用的上一个元素节点
Node prevNode = nextNode.prev;
// 4.3把需要插入的元素包装为一个节点
Node newNode = new Node(null, element, null);
// 4.4更改newNode和prevNode之间的连线
newNode.prev = prevNode;
prevNode.next = newNode;
// 4.5更改newNode和nextNode之间的连线
nextNode.prev = newNode;
newNode.next = nextNode;
// 4.6更新size实际存放元素的个数
size++;
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
//添加
linkedList.add("qq");
linkedList.add("ww");
linkedList.add("ee");
linkedList.add("ff");
linkedList.add("ww");
//删除
//linkedList.remove(0);
//插入
linkedList.add("aa", 3);
//遍历
for(int i = 0;i <linkedList.size(); i++){
System.out.println(linkedList.get(i));
}
}
}