百度百科:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域;
以上是百度百科对链表的定义,理解起来还是挺简单的,下面用JAVA代码实现一下;
//节点,一个链表的组成部分,就像数组是由内存上一段地址连续的空
//间组成一样,链表是由一系列节点组成的。这些节点包含两个部分
//一个是元数据部分,类似于数组中的存储数据,即a[0]这种样式表示的
//数据,一个是对下一个节点的引用next,类似于数组中的下标,唯一
//指定一个链表中的数据的存储位置;
public class NodeTest {
public T idata; //节点存储的元数据
public NodeTest next;//当前节点对下一个节点的引用
public NodeTest(T idata) {
this.idata = idata;
this.next = null;
}
//测试方法,用来直观显示链表的存储数据
public void display(){
System.out.print(idata.toString()+” “);
}
}
好了,以上就是一个节点类,看起来很简单;下面是链表的实现。
/**
* 单端链表,即只能从头至尾遍历
* @author dishihua
*
* @param 泛型
*/
public class LinkTest {
private NodeTest current;
public LinkTest(){
current = null;
}
public boolean isEmpty(){
{
return (current == null);
}
}
/**
* 添加一个节点
* @param data,存储节点数据
*/
public void insertNode(T data){
//将新节点的下一个节点置为当前节点,实际上这个链表的实现是类似栈的,先入后出
NodeTest node = new NodeTest(data);
node.next = current;
//设置新节点为当前节点;以上两个步骤不可颠倒,否则会陷入永远只有一个节点的状况;当前节点的下一个节点是自己;
current = node;
}
/**
* 此方法将删除链表的头节点
*/
public void deleteFirst(){
//删除一个节点,即将当前节点的 next节点的引用移除,实际上,当前节点永远是对链表头节点的引用,
//当前节点的next节点则为链表第二个节点的引用,因此,删除的思想就是将当前节点的引用指向当前节点的
//next引用,即将第二个节点设置为当前节点;
if(!isEmpty()){
current = current.next;
}
}
/**
* 此节点依照节点数据查找指定节点
* @param data,要查找的节点包含的数据
* @return
*/
public NodeTest<T> findByKey(T data){
//新建一个节点引用指向当前节点,如果当前节点的next引用为null表示为找到,否则,不断前移节点
//即不断将当前节点的next引用指向用来查找的节点
NodeTest<T> node = current;
while(node!=null&&!node.idata.equals(data)){
if(node.next==null){
return null;
}
node = node.next;
}
return node;
}
/**
* 此节点依照节点包含的数据删除指定节点,当存在重复数据时,仅会删除一个数据
* @param data 要删除的节点包含的数据
*/
public void deleteByKey(T data){
//删除方法,除了要保存当前节点,用来比较是否是要删除的节点外,还要保存当前节点的上一个节点
//将上一个节点的next引用指向当前节点的next引用,即当前节点不再有节点的next引用指向它,也即被“删除”掉了
NodeTest<T> node = current;
NodeTest<T> previous = current;
while(!node.idata.equals(data)){
if(node.next==null){
return;
}else{
previous = node;
node = node.next;
}
}
if(node.equals(current)){
current = current.next;
}else{
previous.next = node.next;
}
}
public void show(){
NodeTest<T> now = current;
while(now!=null){
now.display();
now = now.next;
}
}
/**
* 在指定的节点后添加一个节点,存在重复时仅在符合条件的第一个节点后添加
* @param data 要添加的节点的数据
* @param key 指定的节点的数据
*/
public void insertAfter(T data ,T key){
NodeTest<T> insertNode = new NodeTest<T>(data);
NodeTest<T> nowNode = current;
NodeTest<T> previous = current;
while(!nowNode.idata.equals(key)&&nowNode.next!=null){
nowNode = nowNode.next;
previous = nowNode.next;
}
//如果指定的节点是链表的头节点,要特殊处理
if(nowNode.equals(current)){
previous = nowNode.next;
nowNode.next = insertNode;
insertNode.next = previous;
}else{
nowNode.next = insertNode;
insertNode.next = previous;
}
}
public static void main(String[] args) {
LinkTest<String> link = new LinkTest<String>();
link.insertNode("node");
link.insertNode("2");
link.insertNode("12");
link.insertNode("23333");
link.insertNode("365");
link.insertNode("365");
link.insertNode("365");
link.insertNode("365");
link.show();
System.out.println();
link.deleteFirst();
link.show();
System.out.println();
link.findByKey("2").display();
System.out.println();
link.insertAfter("我是365", "");
link.show();
}
}