编程导航算法通关村第 1 关 | 链表青铜教程笔记

本文介绍了如何使用Java构建链表,包括创建Node类以及初始化链表的方法。同时详细讲解了在链表中添加元素(首部、中间和尾部)的处理方式和避免的问题,以及删除元素的策略,特别关注了头节点、尾节点和中间节点的处理。文章还提及了双向链表的概念,但未展开详细讨论。
摘要由CSDN通过智能技术生成

本文为编程导航知识星球的算法通关村的学习笔记。

一、Java是如何构造出链表的

①编写Node类,共有两个属性,一个是节点的数据,一个是本类型的的next。构造方法,将data传参进去,即完成node节点的实例。

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

    Node(int x) {
        val = x;
        next = null;
    }
}

②我们的数据类型是int,因此声明一个int型的数组,遍历数组,依次将数组内的数据传入构造方法,如果顺序是第一个,则让Node类型的head对象赋值为第一个节点,如果不是第一个,则将当前的对象的next属性赋值为newNode。

public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5, 6};
        Node head = initLinkedList(a);
        System.out.println(head);
    }

    private static Node initLinkedList(int[] array) {
        Node head = null, cur = null;
        for (int i = 0; i < array.length; i++) {
            Node newNode = new Node(array[i]);
            newNode.next = null;
            if (i == 0) {
                head = newNode;
                cur = newNode;
            } else {
                cur.next = newNode;
                cur = newNode;
            }
        }
        return head;
    }
}

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

以下将头节点称为head,将待插入的节点称为nodeInsert,待插入的位置称为position

①首部添加的时候,需要判断待插入的head是否为空,如果head为空,那么新增的节点即为头节点,赋值给head。如果position为1,将nodeInsert.next赋值为原先的head,然后再将head赋值为nodeInsert。

②在中间和尾部都需要注意位置越界的问题,比如传入的position为0或者超过链表长度+1,即链表长度为5,如果要在尾部插入则position要传入6,而不能大于6。

③在中间插入的时候,遍历到position-1的位置,得到这个节点pNode,要先将待插入的nodeInsert.next属性赋值为pNode.next,先把待插入的nodeInsert的next连接上原先位置的节点,然后再将pNode连接到nodeInsert。因为如果先将nodeInsert.next连接到nodeInsert,那么原来的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;

            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,待删除的位置称为position

①position为头结点,将head赋值为head.next就可以了。

②position为尾节点,则遍历到倒数第二个,即遍历到节点长度size-1的位置,然后让这个位置的节点的next赋值为空即可

③中间位置的删除,遍历到position的前一个节点,使用一个中间变量存储position的节点,再让position-1处的节点的next赋值为position的next节点。比如删除位置4,用一个中间变量将位置3节点的next储存下来,然后将位置3的next属性赋值为位置4的next属性,即将3的next连接到5。

/**
     * 删除节点
     *
     * @param head     链表头节点
     * @param position 删除节点位置,取值从1开始
     * @return 删除后的链表头节点
     */
    public static Node deleteNode(Node head, int position) {
        if (head == null) {
            return null;
        }
        int size = getLength(head);
        //思考一下,这里为什么是size,而不是size+1
        // 删除的位置最多只能等于size,大于size则超出链表长度,自然找不到节点了
        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;
    }

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

占位,再补充。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值