链表使用一组任意的存储单元存放各个元素,这组存储单元可以使连续的,也可以是不连续的,甚至可以零散地分布在内存的某些位置,在java中,我们通过对结点的引用来定义结点,以下是使用泛型的单链表的具体实现,包括对链表的各种操作,如在头部插入节点、删除头结点、删除指定位置的节点、在指定位置插入节点、返回节点的索引值:
package com.example.src;
public class LinkList<T>
{
private Node<T> head;//头结点
private int count = 0;//节点总数
class Node<T>{
private T t;
public Node<T> next;
public Node(T t)
{
this.t = t;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
public LinkList(){
head = null;
}
//在头结点前面插入节点
public void addFirstNode(T t)
{
Node<T> node = new Node<T>(t);
node.next = head;
head = node;
count++;
}
//删除头结点,并返回
public Node<T> deleteFirstNode()
{
if(head == null){
return null;
}
Node<T> tmpNode = head;
head = head.next;
count--;
return tmpNode;
}
//在指定位置插入节点
public void addByIndex(int index, T t)
{
if(index < 0 || index > count-1)
{
throw new IndexOutOfBoundsException("插入越界");
}
if(index == 0){
addFirstNode(t);
}
Node<T> node = new Node<T>(t);
Node<T> current = head;
Node<T> previous = head;
int tmp = 0;
while(tmp != index)
{
previous = current;
current = current.next;
tmp++;
}
previous.next = node;
node.next = current;
count++;
}
//删除指定位置的节点
public Node<T> deleteByIndex(int index)
{
if(index < 0 || index > count-1)
{
throw new IndexOutOfBoundsException("删除越界");
}
int tmp = 0;
Node<T> current = head;//指向当前节点
Node<T> previous = head;//指向当前节点的前一个节点
while(tmp != index)
{
previous = current;
current = current.next;
tmp++;
}
previous.next = current.next;
count--;
return current;
}
//根据索引查找节点
public Node<T> findByIndex(int index)
{
if(index < 0 || index > count-1)
{
throw new IndexOutOfBoundsException("删除越界");
}
int tmp = 0;
Node<T> current = head;
while(tmp != index)
{
current = current.next;
tmp++;
}
return current;
}
//根据数据查找节点的索引值
public int IndexOf(T t)
{
Node<T> current = head;
int index = 0;
while(current.getT() != t)
{
if(current.next == null)
{
return -1;//查找到最后一个节点,没有查找到数据,返回-1
}
current = current.next;
index++;
}
return index;
}
//显示所有节点
public void displayAllNodes()
{
Node<T> current = head;
while(true)
{
System.out.println(current.getT());
if(current.next == null){
//最后一个节点了
break;
}
current = current.next;
}
}
}
对以上代码进行测试:
package com.example.src;
import com.example.src.LinkList.Node;
public class LinkListTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkList<String> ll = new LinkList<String>();
ll.addFirstNode("test1");
ll.addFirstNode("test2");
ll.addFirstNode("test3");
ll.addFirstNode("test4");
ll.displayAllNodes();
//删除指定索引位置的节点
System.out.println("delete:"+ll.deleteByIndex(1).getT());
//在指定位置插入节点
ll.addByIndex(2, "test5");
ll.displayAllNodes();
//根据数据查找节点索引
System.out.println("index:"+ll.IndexOf("test5"));
//根据索引查找节点
System.out.println("data:"+ll.findByIndex(2).getT());
}
}