链表实际上就是用很多个Node节点组成的,每个节点Node又包含对象部分和指向下一个节点的指针。对链表的操作其实归根到底就是对节点指针的操作。
链表的插入:
1、头插法:每次把新插入的节点当着头结点;
2、尾插法:每次把新插入的节点放在尾部;
3、指定位置插入法:每次在指定位置插入某个节点。
链表的删除:
删除指定位置上的某个节点
链表的查询:
1、根据节点位置查询该节点;
2、根据节点查询节点存放的位置
链表是否为空的判断
链表的清空
链表的长度
package com.cn.node;
public class NodeDemo<T> {
private class Node{
private T data;
private Node next;
public Node() {}
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
private Node head;//链表的头结点
private Node tail;//链表的尾节点
int size;
public NodeDemo() {
head = null;
tail = null;
}
public NodeDemo(T data) {
head = new Node(data, null);
tail = head;
size++;
}
/**
* 每次在链表尾部进行插入
* @param element
*/
public void addTailNode(T element) {
if (head == null) {
head = new Node(element, null);
tail = head;
}else {
Node node = new Node(element, null);
tail.next = node;
tail = node;
}
size++;
}
/**
* 每次在链表的头部进行插入
* @param element
*/
public void addHeadNode(T element){
head = new Node(element, head);
if (tail == null) {
tail = head;
}
}
/**
* 在指定的位置插入新节点
* @param element
* @param index
*/
public void addIndexNode(T element, int index) {
if (head == null) {
addTailNode(element);
}else {
if (index == 0) {
addHeadNode(element);
}else {
Node pre = findNodeByIndex(index-1);//找到要插入位置的前一个节点
Node node = new Node(element, pre.next);
//插入后pre的next指向新节点,新节点的next指向原来pre的下一个节点
pre.next = node;
size++;
}
}
}
/**
* 根据节点查询节点存放的位置
* @param element
* @return
*/
public int findIndexByNode(T element) {
Node current = head;
int index = 0;
while (current != null) {
if (current.data.equals(element)) {
return index;
}
current = current.next;
index++;
}
return -1;
}
/**
* 根据节点位置查询该节点
* @param index
* @return
*/
public Node findNodeByIndex(int index) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("链表越界");
}
Node current = head;
int t = 0;
while (current != null) {
if (t == index) {
break;
}
current = current.next;
t++;
}
return current;
}
/**
* 根据节点位置删除指定位置的节点
* @param index
* @return
*/
public T deleteNode(int index) {
Node dNode = null;
if(index < 0 || index > size-1) {
throw new IndexOutOfBoundsException("链表越界");
}
if (index == 0) {
dNode = head;
head = head.next;
}else {
Node pre = findNodeByIndex(index-1);//获取要删除的节点的前一个节点
dNode = pre.next;//要删除的节点就是pre的next指向的节点
pre.next = dNode.next;//删除以后pre的next指向被删除节点之前所指向的next
dNode.next = null;
}
return dNode.data;
}
/**
* 清空链表
*/
public void clear() {
head = tail = null;
size = 0;
}
/**
* 判读链表是否为空
* @return
*/
public boolean isEmpty() {
return size == 0 ? true : false;
}
/**
* 打印链表
*/
public String toString() {
Node node = head;
StringBuffer sb = new StringBuffer();
while (node != null) {
sb.append(node.data+" ");
node = node.next;
}
return sb.toString();
}
public static void main(String[] args) {
NodeDemo<String> nodeDemo = new NodeDemo<String>();
nodeDemo.addTailNode("111");
nodeDemo.addTailNode("222");
nodeDemo.addTailNode("333");
nodeDemo.addTailNode("444");
System.out.println(nodeDemo);
System.out.println("链表的size:" + nodeDemo.size);
System.out.println("删除某个节点的位置:" + nodeDemo.findIndexByNode("333"));
System.out.println("查询指定位置的节点:" + nodeDemo.findNodeByIndex(2).data);
System.out.println("删除指定位置的节点:" + nodeDemo.deleteNode(2));
System.out.println(nodeDemo);
System.out.println("链表是否为空:" + nodeDemo.isEmpty());
nodeDemo.clear();
System.out.println("清空后的链表:" + nodeDemo);
System.out.println("链表是否为空:" + nodeDemo.isEmpty());
}
}
运行后的结果: