算法通关村第一关——链表青铜挑战笔记

理解Java是如何构造出链表的

链表是一种常见的数据结构,由一系列的节点组成。每个节点都包含一个数据元素和一个指向下一个节点的引用。通过这种方式,每个节点都与链表中的下一个节点连接起来,从而形成了链表的结构。

public class ListNode {
    public int val;
    public ListNode next;

    public ListNode(int x) {
        val = x;
        // 这个作用不大,写了更加规范
        next = null;
    }

    /**
     * 符合面向对象的要求,但可以精简舍去
     **/
    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public ListNode getNext() {
        return next;
    }

    public void setNext(ListNode next) {
        this.next = next;
    }

    public static void main(String[] args) {
        ListNode listnode = new ListNode(1);
        System.out.println("当前节点的值:" + listnode.val);
        System.out.println("下一个节点:" + listnode.next);
    }
}

ListNode类包含一个整型数据val和一个指向下一个节点的引用next。通过这种方式,每个节点都可以连接起来,形成一个链表的结构。

链表增加元素,首部、中间和尾部分别会有什么问题,该如何处理?

表头插入

  1. 创建一个新节点 newNode

  2. 将新结点的下一个节点指向链表原来的头节点

返回的时候,需要重新指向表头。

中间插入

  1. 创建一个新节点 newNode

  2. 找到插入的位置position前一个节点

  3. 新节点指向“插入的位置前一个节点”对应的下一个节点。newNode.next = node(position).next

  4. “插入的位置前一个节点”指向新节点node(position).next = newNode

必须在插入位置的前一个位置停下来,让新节点获取它的next,然后在将它指向新节点。顺序反了会丢失后继节点。

结尾插入节点

  1. 创建一个新节点 newNode

  2. 将尾节点指向新节点

/**
     * 插入
     *
     * @param head       头节点
     * @param nodeInsert 待插入的节点
     * @param position   待插入的位置
     * @return 插入后得到的链表头节点
     */
    public static Node insertNode(Node head, Node nodeInsert, int position) {
        // 为空返回
        if (head == null) {
            return nodeInsert;
        }
        // 越界判断
        int size = length(head);
        if (position > size + 1 || position < 1) {
            System.out.println("位置参数越界");
            return head;
        }
        // 在链表开头插入
        if (position == 1) {
            nodeInsert.next = head;
//            return nodeInsert;直接返回新的头节点
            head = nodeInsert;
            return head;
        }

        Node pNode = head;
        int count = 1;
        while (count < position - 1) {
            pNode = pNode.next;
            count++;
        }
        // 插入值先指向null,插入前的位置指向插入值
        nodeInsert.next = pNode.next;
        pNode.next = nodeInsert;

        return head;
    }

链表删除元素,首部、中间和尾部分别会有什么问题,该如何处理?

删除表头结点

  1. 将第二个结点设置成头节点,执行head =head.next;

删除中间结点

  1. 找到删除的位置position前一个节点cur

  2. “插入的位置前一个节点”指向它下一个的下一个cur.next = cur.next.next

删除最后一个结点

  1. 找到删除的位置position前一个节点cur,前驱节点

  2. 判断前驱节点的后继是尾节点,然后将前驱节点的后继置空,执行cur.next = null;

/**
     * 删除节点
     *
     * @param head     头节点
     * @param position 删除节点位置
     * @return 删除后的头节点
     */
    public static Node deleteNode(Node head, int position) {
        if (head == null) {
            return null;
        }
        int size = length(head);
        if (position > size || position < 1) {
            System.out.println("越界");
            return head;
        }
        if (position == 1) {
            // curNode就是链表的新head
            return head.next;
        } else {
            Node node = head;
            int count = 1;
            if (count < position - 1) {
                node = node.next;
                count++;
            }
//            node.next = node.next.next; 简化版
            Node curNode = node.next;
            node.next = curNode.next;
        }

        return head;
    }

双向链表是如何构造的,如何实现元素的插入和删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值