【链表】算法通关村第一关之青铜挑战(Java)

目录

一、链表的结构

 二、如何创建链表

 2.1.一个简单的链表实例,用于演示JVM怎么构造链表的

 2.2.LeetCode中算法题中经常使用这样的方式来创建链表:

三、遍历链表

四、链表的插入

4.1.头插

 4.2.尾插

 4.3.中间插

五、链表的删除


从这篇文章开始,正式进入算法学习(纯小白)~

这篇文章是链表的青铜难度学习打卡

一、链表的结构

链表是最基础也是最实用的数据结构之一,常用的链表有单链表双向循环链表等。

以单链表为例子,节点中一般包含当前节点值以及下一个节点的引用

 二、如何创建链表

 2.1.一个简单的链表实例,用于演示JVM怎么构造链表的

/**
 * 一个简单的链表实例,用于演示JVM怎么构造链表的
 */
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;

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

其中val是要存储的值,next是指向下一个结点的引用。 

注意打印head

 2.2.LeetCode中算法题中经常使用这样的方式来创建链表:

public class ListNode {
        //创建链表
        public int val;
        public ListNode next;
        public ListNode(int val){
            this.val = val;
            this.next = null;
        }
}

三、遍历链表

注意不要丢了 head

public static int getListLength(ListNode head){
    int len = 0;
    ListNode cur = head;
    while(cur != null){
        len++;
        cur = cur.next;
    }
    return len;
}

这里我先创建了一个链表为135349null

public class MyListNode {
    public  static  ListNode head;

    public static ListNode getMyListNode(){
        ListNode head = new ListNode(1);
        ListNode node2 = new ListNode(3);
        ListNode node3 = new ListNode(5);
        ListNode node4 = new ListNode(3);
        ListNode node5 = new ListNode(4);
        ListNode node6 = new ListNode(9);
        head.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        return head;
    }


    public static void main(String[] args) {
        MyListNode myLinkedList = new MyListNode();
        head = getMyListNode();
        printList();
    }

遍历

//打印
    public static void printList(){
        ListNode curr = head;
        while(curr != null){
            System.out.print(curr.val + " - ");
            curr = curr.next;
        }
        System.out.println("null");
    }

四、链表的插入

插入分为 头插、中间插、尾插

4.1.头插

链表表头插入新结点非常简单,容易出错的是经常会忘了head需要重新指向表头。 链表表头插入新结点非常简单,容易出错的是经常会忘了Head需要重新指向表头.

总结就是 head=newNode
上代码

 public static void addFirst(int val){
        ListNode newHead = new ListNode(val);
        newHead.next = head;
        head = newHead;
    }

 4.2.尾插

表尾插入就比较容易了,我们只要将尾结点指向新结点就行了。
上代码

public static  void addLast(int val){
        ListNode curr = head;
        if(head == null){
            head = new ListNode(val);
            return;
        }
        while(curr.next != null){
            curr = curr.next;
        }
        curr.next = new ListNode(val);
    }

 4.3.中间插

在中间位置插入,我们必须先遍历找到要插入的位置,然后将当前位置接入到前驱结点和后继结点之间,但是到了该位置之后我们却不能获得前驱结点了,也就无法将结点接入进来了。
为此,我们要在目标结点的前一个位置停下来,也就是使用cur.next的值而不是cur的值来判断,这是链表最常用的策略。

/**
     * 中间插入
     *
     */
    public static  void addMiddle(int index,int val){

        ListNode curr = head;
        //长度
        int size = getLength(getMyListNode());

        if(index < 0||index > size){
            System.out.println("index不合法!当前size为" + size);
            return;
        }else if(head == null||index == 0){
            addFirst(val);
        }else if(index == size){
            addLast(val);
        }else {
            int count = 0;
            while(count < index-1){
                curr = curr.next;
                count++;
            }
            ListNode newNode = new ListNode(val);
            newNode.next = curr.next;
            curr.next = newNode;
            size++;
        }
    }

addMiddle(3,888);

 综上,我们写出链表插入的方法如下所示:

public static ListNode insertNode(ListNode head, ListNode newNode, int position){
    if(head == null){
        return newNode;
    }
    //越界判断
    int size = getLength(head);
    if(position > size + 1 || position < 1){
        System.out.println("位置参数越界");
        return head;
    }
    //表头插入
    if(position == 1){
        newNode.next = head;
        head = newNode;
        return head;
    }
    //表中插入&表尾插入
    ListNode cur = head;
    int count = 1;
    while(count < position - 1){
        cur = cur.next;
        count++;
    }
    newNode.next = cur.next;
    cur.next = newNode;
    return head;
}

五、链表的删除

public static ListNode deleteNode(ListNode head, int position){
        if(head == null){
            return null;
        }
        //越界判断
        int size = getLength(getMyListNode());
        //注意position > size与插入链表节点有所区别
        if(position > size || position < 1){
            System.out.println("位置参数越界");
            return head;
        }
        //表头删除
        if(position == 1){
            return head.next;
        }
        //表中删除&表尾删除
        ListNode cur = head;
        int count = 1;
        while(count < position - 1){
            cur = cur.next;
            count++;
        }
        cur.next = cur.next.next;
        return head;
    }

随机测试两个

 打印测试结果,正确!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值