单端链表的实现

百度百科:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域;
以上是百度百科对链表的定义,理解起来还是挺简单的,下面用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();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值