数据结构与算法学习笔记 Chapter1 链表(1)

何为链表?

链表由很多个节点组成,每个节点包括该节点的数据以及指向列表下一个节点的地址。 其中链表的内存中不一定是连续集中存储的。 单个节点结构:

Java如何构造链表

完成下面的链表,也就是通过栈中的地址找到val(1)的值,再通过val(1)节点中存放的val(2)的地址找到val(2)的值,依次类推。

java 复制代码
package lukasy.chapter1_linklist.level1;

import org.w3c.dom.Node;

public class BasicLink {
    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;
    }

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

        public Node(int x) {
            val = x;
            next = null;
        }
    }
}
java 复制代码
package lukasy.chapter1_linklist.level1;

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

    public ListNode(int x) {
        val = x;
        next = null;
    }
}

链表的CRUD

在单链表中,任何操作都将链表从头到尾逐个访问 ,所以一定要找到表头的位置

java 复制代码
public static int getListLength(Node head) {
        int length = 0;
        Node node = head;
        while (node != null) {
            length++;
            node = node.next;
        }
        return length;
    }

链表的插入

  1. 在表头插入新的节点

首先要创建一个新的节点,让新的节点的指针域指向原先的head节点,再将head指向新的节点。

  1. 在表中间插入新的节点

首先要确定插入节点位置位于哪两个节点之间(也就是新节点的前驱和后继),然后将新节点的指针域指向前驱节点的指针域(也就是新节点指针域指向后继节点),之后让前驱节点的指针域指向新节点 。这两步顺序不能错,是以为如果直接让前驱节点的指针域指向新的节点,那么前驱节点原本的指针域就会丢失,也就是说新的节点的指针域将不会指向下一个后继节点。 3. 在表尾插入新的节点

只需要将表尾节点的指针域指向新的节点即可。

java 复制代码
 /**
     * 链表插入
     *
     * @param head       链表头节点
     * @param nodeInsert 待插入节点
     * @param position   待插入位置,从1开始
     * @return 插入后得到的链表头节点
     */
    public static Node insertNode(Node head, Node nodeInsert, int position) {
        if (head == null) {
            //待插入节点为表头的节点
            return nodeInsert;
        }
        //检查判断存放元素个数
        int size = getListLength(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;
        //创建一个count来统计pNode移动的位置
        int count = 1;
        while (count < position - 1) {
            pNode = pNode.next;
            count++;
        }
        nodeInsert.next = pNode.next;
        pNode.next = nodeInsert;

        return head;
    }

链表的删除

  1. 删除表头的节点

直接将head指向下一个next节点即可,JVM会回收原来的头节点。

  1. 删除表尾的节点

遍历表尾节点的前一个节点,判断该节点的指针域是否指向的是尾节点,如果是的话直接将该节点指针域指向null,同样地,JVM会回收原来的尾节点。

  1. 删除表中的节点

找到要删除的节点,将该节点前驱节点的指针域指向该节点的后继节点 即可,同样地,JVM会回收该节点。

java 复制代码
/**
     * 删除节点
     *
     * @param head     头节点
     * @param position 删除节点位置,取值从1开始
     * @return 删除后的链表头节点
     */
    public static Node deleteNode(Node head, int position) {
        if (head == null) {
            return head;
        }
        int size = getListLength(head);
        if (position > size || position < 1) {
            System.out.print("输入参数有误");
            return head;
        }
        if (position == 1) {
            head = head.next;
        } else {
            Node cur = head;
            int count = 1;
            while (count < position - 1) {
                cur = cur.next;
                count++;
            }
            cur.next = cur.next.next;
        }
        return head;
    }
相关推荐
向前看-1 小时前
验证码机制
前端·后端
XH华2 小时前
初识C语言之二维数组(下)
c语言·算法
超爱吃士力架3 小时前
邀请逻辑
java·linux·后端
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_3 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子3 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡3 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin3 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码4 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7244 小时前
LILAC采样算法
人工智能·算法·机器学习