java -编写一个简单的单链表的功能

单链表

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据

废话不多说直接上代码

package com.demp.linkListd;

import org.junit.Test;



/**
 * 头结点是第一结点,只是一般没有数据
 * 头结点后面是首元结点,即第一个存放数据的结点
 * 做删除操作时,一般需要返回所删除结点的数据,所以一般不删除头结点
 * 如果你执意要删的话,当然也可以,
 * 因为链表分为有头结点的链表和无头结点的链表
 * 这个单链表是没有头节点的,也就是头节点是由数据的
 */

public class linkListDemo {

    //链表结构通俗的讲就是数据和地址符,一个节点里面有一个数据和一个地址符(指下一个节点的地址符)
    private Node head = null;//创建一个空的头节点


    //查询节点的长度
    public long  get_length(){
        long len=0;
        Node currNode=head;
        if (currNode==null){
            len=0;
        }else{
            while(currNode.next!=null){  //循环判断链表的长度
                len++;
                currNode=currNode.next;
            }

        }
        return len;
    };




    //添加节点
    public  void add(String data){
        Node newNode= new Node(data);
        if (head==null){
            head=newNode; //如果head为null说明这个链表里没有数据,把第一个传进来的数据放在第一个中
            return;
        }else{
            //currNode是指当前的所在节点,相当与指针
            Node currNode=head;
            //当当前节点的next不为空,说明还有下个节点,然后将下个节点赋值给当前节点
            while (currNode.next!=null){
                    currNode=currNode.next;//将下个节点赋值给当前节点,相当与移动指针
            }
            //跳出循环时,当前节点为最后一个节点,因为最后一个 节点的next为null
            //然后将当前节点(最后一个节点)的next赋值为新节点的地址符,最后一个节点next未赋值默认未null
            currNode.next = newNode;

        }
    }


    //删除节点,根据节点数据删除节点,此方法只能删除从head开始第一个相同的数据的节点
    public Node delet(String data){
        if (head==null){
            return head;
        }
        Node currNode = head;
        //如果删除的是第一个节点,则直接将当前指针往后移动一位,如果没有下一个节点,则删除后的节点未null
        if (data.equals(head.data)){
               currNode=head.next;
        }else{
            //当第一个节点不删除时
            currNode=head;
            //变量名为前一个节点,实际是当前节点通过遍历当前节点,比较下一个节点与参数是否一样,然后将当前节点的next替换成下一个节点next就实现了删除
            //因为head头节点我们处理过了,所以在这里我们从head之后的节点开始处理就行了,所以在下面的循环比较中,没有比较头节点
            Node preNode=currNode;
            Node nextNode=preNode.next;

            while (nextNode != null) {
                if (data.equals(nextNode.data)) {
                    //将nextNode节点的next给preNode的next完成删除
                    //无需考虑最后一个节点的删除,最后一个节点的next为null赋值给前一个节点next,也会实现伤处最后一个节点
                    preNode.next=nextNode.next;
                    break;
                }
                    //将下一个节点赋值给当前节点,实现指针的移动
                    preNode=nextNode;
                    //下下个节点赋值给下个节点
                    nextNode=preNode.next;
//                    System.out.println("preNode :" + preNode + "nextNode :" + nextNode );

            }
        }
        return currNode;
    }



    //删除节点,根据节点数据删除节点,删除链表中的所有相关数据
    public Node deletAll(String data){
        if (head==null){
            return head;
        }
        Node currNode = head;
        //如果删除的是第一个节点,则直接将当前指针往后移动一位,如果没有下一个节点,则删除后的节点未null
        if (data.equals(head.data)){
            currNode=head.next;
        }else{
            //当第一个节点不删除时
            currNode=head;
            //变量名为前一个节点,实际是当前节点通过遍历当前节点,比较下一个节点与参数是否一样,然后将当前节点的next替换成下一个节点next就实现了删除
            //因为head头节点我们处理过了,所以在这里我们从head之后的节点开始处理就行了,所以在下面的循环比较中,没有比较头节点
            Node preNode=currNode;
            Node nextNode=preNode.next;

            while (nextNode != null) {
                if (data.equals(nextNode.data)) {
                    //进行删除
                    preNode.next=nextNode.next;
                    //删除后在新的链表中将指针忘后移动
                    nextNode=preNode.next;
                    System.out.println("preNode :" + preNode + "nextNode :" + nextNode );
                    continue;
                }
                //将下一个节点赋值给当前节点,实现指针的移动
                preNode=nextNode;
                //下下个节点赋值给下个节点
                nextNode=preNode.next;

            }
        }
        return currNode;
    }

    //删除节点,根据索引删除节点
    public boolean deleteByIndex(int index){
        if (index<1 || index > get_length() || head==null){
            System.out.println("索引超出或者链表为空");
            return false;
        }
        //如果是删除第一个则单独处理
        if (index==1){
            head=head.next;
            return true;
        }
        int count = 1 ; //统计循环次数来决定删除那个,因为是从第二节点开始,所以起始为1
        Node preNode = head;
        Node nextNode= preNode.next;
        while (nextNode!=null){
            count ++;
            //如果索引相同则删除,并返回
            if (index==count){
                preNode.next=nextNode.next;
                return true;
            }
            preNode=nextNode;
            nextNode=preNode.next;
        }
        return true;
    };

    //查找索引,根据data返回索引
    public int getData(String  data){
        if (data.isEmpty()||head==null){
            return -404;
        }
        int count = 1 ;
        Node preNode = head;
        while (preNode!=null){
            if (data.equals(preNode.data)){
                return count;
            }
            count++;
            preNode=preNode.next;
        }
        System.out.println("没有该数据");
        return -404;
    }

//封装一个节点类
    public  class Node {
        private String data;
        private Node next;
       public  Node(String data){
            this.data=data;
        }
    }



    @Test
    public void demo(){
        for (int i = 0 ; i < 5 ; i++){
            add(i+"s");
        }

        add(1+"s");
        add(3+"s");
        add(6+"s");
//        Node delet = deletAll("1s");
//        boolean index = deleteByIndex(7);
//        System.out.println(index);
        int data = getData("6s");
        System.out.println(data);

        Node currNode= head;

        //循环打印列表,从head第一个节点开始
        System.out.println(head.data);
        while(currNode.next!=null){

            currNode=currNode.next;  //移动指针
            System.out.println(currNode.data);
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值