Java实现单链表

前言:

🎈链式存储数据分为顺序存储和链表存储,链表就是存在多个节点,每个节点之间存在数据域和指向域(存储下一个节点的引用),这样的数结构可以保证每个节点之间相互关联,从而达到数据之间的关联。

🎈不同的数据结构,就会有不同优缺点。链表相对于顺序表,增加数据不需要挪动数据,只需要将新的节点插入即可,删除数据只需要删除相应的节点等等。顺序表是一块连续的内存,而链表是以节点构成数据相关联,内存都是分布开的,对于一些数据的访问顺序表优于链表,等等一些优点。各有所长,根据需求来选择合适的数据存储方式,以提高代码效率。

🎈单链表的实现,需牢牢把把握住结构的特点,每个节点是相互关联的。对链表进行增删查改等操作时,需维护好这样的结构特点,必要时可画图帮助自己理解。在清空链表时,需了解JVM对于内存的回收机制,当一个对象没有被引用时,就会被JVM所回收。意味着,只需要将头节点的next置空,那么一连串的节点都会被回收。

代码实现

public class SingleLinkedList {
    static class ListNode {
        private int val;
        private ListNode next;

        private ListNode(int val) {
            this.val = val;
        }

    }
    private ListNode head;
    //判断下一个节点的值,找上一个节点
    private ListNode findPrevNode(int key) {
        ListNode cur = head;
        while(cur.next != null) {
            if(cur.next.val == key) {
                return cur;
            }
            cur = cur.next;
        }
        return null;

    }
    //狗撵兔法找上一个节点
    private ListNode findPrevNode2(int key) {
        ListNode cur = head;
        ListNode prev = null;
        //限制cur,防止空指针异常
        while(cur != null && cur.val != key) {
            prev = cur;
            cur = cur.next;
        }
        if(cur == null) {
            return null;
        }
        return prev;
    }
    public void remove(int key) {
        if(this.head == null) {
            System.out.println("链表为空");
            return;
        }
        //删头节点
        if(this.head.val == key) {
            head = head.next;
            return;
        }

        ListNode prev = findPrevNode2(key);
        if(prev == null) {
            System.out.println("没有你要删除的数据");
            return;
        }
        prev.next = prev.next.next;
    }
    //前后指针遍历
    public void removeAllKey(int key) {
        ListNode prev = head;
        ListNode cur = head.next;
        while(cur != null) {
            if(cur.val == key) {
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        if(head.val == key) {
            head = head.next;
        }
    }
    public boolean contains(int key) {
        ListNode cur = this.head;
        while(cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    public void addIndexOf(int index, int date) throws IndexIllegalExpection{
        //首先判断index的合法性
        if(index < 0 || index > size()) {
            System.out.println("位置不合法");
            throw new IndexIllegalExpection("位置不合法");
        }
        if(index == 0) {
            addFirst(date);
        }
        if(index == size()) {
            addEnd(date);
        }

        ListNode cur = this.head;
        //找上一个节点
        while(index - 1 != 0) {
            cur = cur.next;
            index--;
        }
        ListNode newNode = new ListNode(date);
        newNode.next = cur.next;
        cur.next = newNode;
    }

    public void addEnd(int date) {
        ListNode newNode = new ListNode(date);
        ListNode cur = head;
        if(cur == null) {
            head = newNode;
            return;
        }
        //找尾
        while(cur.next != null) {
            cur = cur.next;
        }
        cur.next = newNode;


    }
    public void addFirst(int date) {
        ListNode newNode = new ListNode(date);
        newNode.next = this.head;
        this.head = newNode;
    }
    public void display() {
        ListNode cur = this.head;
        while(cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
    }
    public int size() {
        int count = 0;
        ListNode cur = this.head;
        while(cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }
    //没有引用则被jvm回收
    public void clear() {
        this.head = null;
    }
    public void createNode() {
        ListNode Node1 = new ListNode(1);
        ListNode Node2 = new ListNode(2);
        ListNode Node3 = new ListNode(3);
        ListNode Node4 = new ListNode(4);
        ListNode Node5 = new ListNode(5);
        this.head = Node1;
        Node1.next = Node2;
        Node2.next = Node3;
        Node3.next = Node4;
        Node4.next = Node5;
    }

}

自定义异常

public class IndexIllegalExpection extends RuntimeException{
    public IndexIllegalExpection() {

    }
    public IndexIllegalExpection(String message) {
        super(message);
    }
}

测试模块

public class Main {
    public static void main(String[] args) {
        SingleLinkedList linkedList = new SingleLinkedList();
        linkedList.createNode();
        linkedList.addFirst(8);
        linkedList.addFirst(2);
        linkedList.addEnd(25);
        try {
            linkedList.addIndexOf(2,95);
            linkedList.addIndexOf(5,99);
        } catch (IndexIllegalExpection e) {
            e.printStackTrace();
        }
        linkedList.remove(25);
        linkedList.removeAllKey(2);

        linkedList.clear();
        linkedList.display();
        System.out.println();
        System.out.println(linkedList.contains(257));
        System.out.println("大小:" + linkedList.size());

    }
}

小结:

🐵在学习不同的数据结构时,需抓住每种结构的特点,根据这种特点去思考,会有不一样的收获。

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小太空人w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值