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

概念提要
链表:由同类型数据元素构成的有序线性序列,像一条铁链一样,一环接一环。

结点和头结点:结点可以认为是一个数据+指向这个数据的指针构成的,多个这样的结点构成了链表,而位于单链表首位的结点称为头结点

虚拟节点:是头结点的前一个结点,称为dummyNodedummyNode.next=head,也就是说虚拟结点的next指针指向头结点

  1. Java是如何构造出链表的

    栈区存引用即指针,堆区存对象

在这里插入图片描述

左边栈区存着指向Student对象的地址,根据引用找到右边堆区存储的Student1/2/3/4对象,每个对象结点又存了指向下一个对象的指针,由此构造出一个单链表。

Java当中规范的单向链表应该这样定义:

package ChapterOneListNode;

public class ListNode {
    private int data;
    private ListNode next;
    public ListNode(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public ListNode getNext() {
        return next;
    }

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

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

    向链表中插入新的元素,需要考虑三种情况,链表的头部、身部、尾部。

    • 头部插入元素,只需创建一个新的结点再将其连接到原来的链表即可,即newNode.next = head,再让head = newNode,这样头结点就变为新插入的结点

    • 在链表中间位置插入,需要找到要插入位置的前面一个节点,给newNode架桥,先让newNode.next = nextNode,接着让cur.next = newNode,桥就架好了

在这里插入图片描述

  • 尾部插入直接将尾结点指向新结点即可,tailNode.next = newNode

链表插入方法如下:

public static void 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;
    }
  1. 链表删除元素,首部、中间和尾部分别会有什么问题,该如何处理?

    链表删除结点也需要考虑头部、身部、尾部三种情况

    • 头部删除结点只需要将head = head.next即可
    • 删除链表中间的结点也需要找到要删除结点的前一个结点位置,然后让cur.next = cur.next.next即可
    • 删除尾部结点时也需要找到尾部结点的前一个结点,然后判断cur.next的值是否为尾部结点的值,如果是,只需要cur.next = null即可

    删除链表节点方法如下:

        public static Node deleteNode(Node head, int position) {
            if (head == null) {
                return null;
            }
            
            int sizeOfNodeList = getListLength(head);
            if (position > size || position < 1) {
                System.out.println("输入的参数有误");
                return head;
            }
            if (position == 1) {
                return head.next;
            } else {
                Node cur = head;
                int count = 1;
                while (count < position-1) {
                    cur = cur.next;
                    count++;
                }
                cur.next = cur.next.next;
            }
            
        }
    
  2. 双向链表是如何构造的,如何实现元素的插入和删除

    双向链表:和单向链表一样都是通过指针将一个个结点连接起来,和单链表不同的地方在于单链表每个结点的指向只有一个,双向链表每个结点都有两个指针,prevnext

在这里插入图片描述

双向链表构造如下:

package ChapterOneListNode;

public class DulDirectionListNode {
    private int data;
    private DulDirectionListNode next;
    private DulDirectionListNode prev;
    
    public DulDirectionListNode(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public DulDirectionListNode getNext() {
        return next;
    }

    public void setNext(DulDirectionListNode next) {
        this.next = next;
    }
    
    public DulDirectionListNode getPrev() {
        return prev;
    }

    public void setPrev(DulDirectionListNode prev) {
        this.prev = prev;
    }
}

实现元素的插入和删除都需要考虑结点的两个指针指向的改变,基于单向链表的插入和删除再进行双向列表的插入和删除就比较容易理解了,不再赘述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值