java单链表实现

链表介绍:
链表是一种非常使用的数据结构,它解决了数组的一些缺点,如数组一经定义,数组的大小就固定了,但在实际开发中,我们可能不确定数组的大小,更多是需要的是一种可以自动扩充的数据结构,而链表就可以很好的实现这一点,很多时候我们在做的事可能就是增删改查,大家都知道数组的增加和删除都需要大量移动数组中的元素,所以数组在增加和删除方面效率偏低,而链表很好的解决了这个问题,链表不需要移动元素便可完成增加和删除,所以链表这种数据结构显得非常重要

实现思路:
采用带一个头结点,尾插法实现,头节点知识表示链表的第一个位置,其中不存放数据,这样可以对链表进行整体的操作,如当删除第一个节点时,这种方式可以直接删除,

增加,查询,修改都比较简单,给一个删除节点的图示和说明:
如下图所示,假设我们需要删除的节点是node2,此时辅助节点tempNode的位置应该是node1才对,因为单链表只有一个尾指针,如果辅助节点的位置指向了待删除的节点,那么该节点就不能自己删除自己,它只能删除它后面的节点,相反,如果辅辅助节点的位置是待删除节点的上一个节点,如图中的node1,直接执行tempNode.next=tempNode.next.next,即可完成对node2节点的删除
在这里插入图片描述


package com.lugang.list;
//链表类
public class SingleList {
    private int size=0;//记录链表结点的个数
    private Node head=new Node();//各种操作都需要一个临时节点来替代头节点,不要直接对头节点进行操作,因为增删改查一开始都需要找到头节点,所以头结点的位置不能动
    public void add(Node newNode){
        Node tempNode=head;
        while(true){
            if(tempNode.next==null){
                break;
            }
            else{
                tempNode=tempNode.next;
            }
        }
        //退出循环时说明tempNode.next=null,此时让tempNode.next=newNode,即可完成添加操作
        tempNode.next=newNode;
        size++;
    }
    public void show(){
        //需要判断链表是否为空
        if(head.next==null){
            System.out.println("链表为空");
            return;
        }
        else{
            //因为链表不为空 直接将tempNode=head.next,退出循环的条件为tempNode是否为空
            Node tempNode=head.next;
            while(true){
                if(tempNode==null){
                    break;
                }
                else{
                    //需要重写toString
                    System.out.println(tempNode);
                    tempNode=tempNode.next;
                }
            }

        }
    }
    public int size(){
        return size;
    }

    /**
     * 
     * @param value 查找结点的值
     * @return 如果找到就返回找到的节点,找不到就返回空值
     */
    public Node find(int value){
        if(head.next==null){
            //使用异常退出
            throw new RuntimeException("链表为空");
        }
        else{
            boolean flag=false;
            Node tempNode=head.next;
            while(true){
                //找到最后不管查找节点存不存在都退出
                if(tempNode==null){
                    break;
                }
                //找到退出
                if(tempNode.data==value){
                    //标志找到
                    flag=true;
                    break;
                }
                //向后移动
                else{
                    tempNode=tempNode.next;
                }
            }
            //退出循环需要用flag判断是否找到
            if(flag==true){
                //找到节点,直接将tempNode返回
                return tempNode;
            }
            else{
                //没找到,返回空值
                return null;
            }
        }
    }

    /**
     *
     * @param index 待修改元素的缩影
     * @param value 待修改元素的值
     */
    public void update(int index,int value){
        if(head.next==null){
            throw new RuntimeException("链表为空,无法修改");
        }
        else{
            //对索引的值进行校验
            //设定链表的第一个索引为一,非头节点
            if(index<1||index>size()){
                System.out.println("错误的索引");
                return;
            }
            else{
                Node tempNode=head.next;
                //找到位置
                for(int i=1;i<index;i++){
                    tempNode=tempNode.next;
                }
                //退出循环就修改
                tempNode.data=value;
            }
        }
    }
    public void delete(int value){
        if(head.next==null){
            throw new RuntimeException("链表为空,无法删除");
        }
        else{
            boolean flag=false;
            Node tempNode=head;
            while(true){
                if(tempNode.next==null){
                    break;
                }
                if(tempNode.next.data==value){
                    flag=true;
                    break;
                }
                else{
                    tempNode=tempNode.next;
                }
            }
            if(flag==true){
                tempNode.next=tempNode.next.next;
                size--;
            }
            else{
                System.out.println("所删除的节点在链表中不存在");
            }
        }
    }
}
//节点类,节点类也可以写到链表类的内部,采用内部类的方式实现更好
class Node{
    public int data;//数据域
    public Node next;//指向下一个节点引用,默认为空
    public Node(int data){
        this.data=data;
    }
    public Node(){}

    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                '}';
    }
}
package com.lugang.list;
//测试类
public class SingleListTest {
    public static void main(String[] args) {
        Node node1=new Node(1);
        Node node2=new Node(2);
        Node node3=new Node(3);
        Node node4=new Node(4);
        Node node5=new Node(5);
        SingleList list=new SingleList();
        list.add(node1);
        list.add(node2);
        list.add(node3);
        list.add(node4);
        list.add(node5);
        list.show();
        //测试查找
        Node node = list.find(1);
        if(node==null){
            System.out.println("节点不存在");
        }
        else{
            System.out.println(node);
        }
        //测试修改
        list.update(1,12);
        list.update(5,34);
        System.out.println("**********************");
        list.show();
        //测试删除
        list.delete(1);
        list.delete(4);
        System.out.println("************************");
        list.show();
        System.out.println(":::::::::::::::::::::::::::::");
        list.delete(34);
        list.show();
    }
}

注:代码很多地方都可以修改,如循环部分,可以添加泛型实现,此次的代码网最简单的方向写,本人第一篇文字,如果有错还希望各位纠正,文章内容很基础,自己就是做一下记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值