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

概念:

链表是一个一个相同节点的 数据元素 组成的一个对象。

对象与对象之间是如何进行联系的? 

每一个Object对象有一个 ‘自己‘,用于记录下一个链接的对象。

static class Node {
    public int val;
    public Node next;
}

 链表的增删改查:

遍历链表:

链表只能从头结点往后一次访问,循环结束的点为当前节点为null。

public static int getLength(Node head) {
    int length = 0;
    Node node = head;
    while (node != null) {
        length++;
        node = node.next;
    }
    return length;
}

链表插入: 

考虑三种情况:

  • 头部插入

新节点的下一个只想当前头节点,记住头节点需更新为新节点(记得判断头结点是否为null)

  • 中间插入

链表为线性结构,要插入节点必须找到其前一个节点。

插入顺序为:必须先将新节点的 next 和 cur.next先连接,再将cur.next指向新节点。如果将顺序对调,会发现断链,无法找到原先的cur.next节点。

  • 尾部插入

和头部一样,只需遍历到最后一个节点,他的下一个节点指向新节点就行

/**
     * 链表插入
     *
     * @param head       链表头节点
     * @param nodeInsert 待插入节点
     * @param position   待插入位置,取值从2开始
     * @return 插入后得到的链表头节点
     */
    public static Node insertNode(Node head, Node nodeInsert, int position) {
        // 需要判空,否则后面可能会有空指针异常
        if (head == null) {
            return nodeInsert;
        }
        //越界判断
        int size = getLength(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++;
        }
        nodeInsert.next = pNode.next;
        pNode.next = nodeInsert;

        return head;
    }

链表删除: 

删除和添加类似,分为三种情况:头、中、尾

  • 删除头部

删除表头元素还是比较简单的,一般只要执行head=head.next就行了。如下图,将head向前移动一次之后,原来的结点不可达,会被JVM回收掉。

  • 删除最后一个结点

删除的过程不算复杂,也是找到要删除的结点的前驱结点,这里同样要在提前一个位置判断,例如下图中删除40,其前驱结点为7。遍历的时候需要判断cur.next是否为40,如果是,则只要执行cur.next=null即可,此时结点40变得不可达,最终会被JVM回收掉。

  • 删除中间节点

找到前继节点。cur.next = cur.next.next;

/**
     * 删除节点
     *
     * @param head     链表头节点
     * @param position 删除节点位置,取值从1开始
     * @return 删除后的链表头节点
     */
    public static Node deleteNode(Node head, int position) {
        if (head == null) {
            return null;
        }
        int size = getLength(head);
        if (position > size || position <1) {
            System.out.println("输入的参数有误");
            return head;
        }
        if (position == 1) {
            //curNode就是链表的新head
            return head.next;
        } else {
            Node cur = head;
            int count = 1;
            while (count < position - 1) {
                cur = cur.next;
                count++;
            }
            Node curNode = cur.next;
            cur.next = curNode.next;
        }
        return head;
    }

注意点:

我们在赋值Node cur = head时,所有对cur的操作,都是对head的实际操作,因为赋值时是类似于Integer的地址赋值,是直接操作对象的。

连表增加元素和删除元素时,一定要注意顺序,必须考虑到断链的风险,一定要先 ‘保存住’ 下一个对象在操作。反正我们这个新对象是跑不掉的,哈哈哈哈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林深时见璐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值