编程导航算法通关村第一关|链表(青铜挑战)

一、什么是链表

链表在内存中的位置不一定是连续的,如下图所:数据元素随机存储在内存中,通过指针维系数据之间一对一的逻辑关系,这样的存储结构就是链表
链表图

链表由多个节点组成,每个节点又是由指向下一个节点的地址组成,所以链表在内存中存储的位置不一定是连续的,节点之间的关联是通过节点中存储的地址进行关联。
对于单链表,如果知道了第一个元素,就可以通过遍历的方式访问整个链表,因此第一个节点最重要,称之为头节点

二、如何构造链表

链表的节点是由指向下一个节点的地址组成,所以在定义实体类时,需要最基本的两个属性,如下所示,val用来存储数据,next用来存储指向下一个节点的地址;

下面代码中创建了三个对象,headNode(头节点),secondnNode,thirdNode。其中secondnNode赋值给了headNode中的next属性,thirdNode赋值给了secondnNode中的next属性。

/**
 * 在算法中最常用的链表定义方式
 */
public class ListNode {
    public int val;
    public ListNode next;

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

    public static void main(String[] args) {
        ListNode headNode=new ListNode(1);
        ListNode secondnNode=new ListNode(8);
        ListNode thirdNode=new ListNode(5);
        headNode.next = secondnNode;
        secondnNode.next = thirdNode;
        System.out.println(headNode);
    }
}

通过Debug可以看出,整体代码执行后,三个节点组成了一个简单的线性访问,可以通过headNode节点逐个向后访问。
在这里插入图片描述

三、链表的基本操作

3.1遍历链表

/**
  * 获取链表长度
  * 
  * @param headNode 表头
  * @return
  */
private static void getListLength(ListNode headNode) {
    int length = 0;
    ListNode node = headNode;
    while (node != null) {
        node = node.next;
        length++;
    }
    System.out.println(length);
}

3.2插入链表

1)插入节点位置在第一个:直接将插入节点的next指向头节点t即可;
2)插入节点位置非第一个:则只需要遍历到插入节点的前一个元素,然后将插入节点的next指向遍历当前节点的next,当前节点的next指向插入节点的next即可;

/**
  * 插入操作
  * 
  * @param headNode 表头
  * @param nodeInsert 插入节点
  * @param position 插入位置
  * @return
  */
 private static ListNode insertNode(ListNode headNode, ListNode nodeInsert, int position) {
     if (headNode == null) {
         return nodeInsert;
     }
     int listLength = getListLength(headNode);
     if (position > listLength + 1 || position < 1) {
         System.out.println("下标越界");
         return headNode;
     }

     if (position == 1) {
         nodeInsert.next = headNode;
         return nodeInsert;
     }

     int i = 1;
     ListNode node = headNode;
     while (i < position - 1) {
         i++;
         node = node.next;
     }
     nodeInsert.next = node.next;
     node.next = nodeInsert;
     return headNode;
 }

3.3删除链表

1)删除节点位置在第一个:直接返回headNode.next即可;
2)插入节点位置非第一个:则只需要遍历到删除的前一个元素,然后将当前节点的next指向下个节点的next即可;

/**
  * 删除节点
  * 
  * @param headNode 表头
  * @param position 删除节点位置
  * @return
  */
 private static ListNode deleteNode(ListNode headNode, int position) {
     int listLength = getListLength(headNode);
     if (position > listLength || position < 0) {
         System.out.println("下标越界");
         return headNode;
     }
     int i = 1;
     ListNode node = headNode;
     while (i < position - 1) {
         i++;
         node = node.next;
     }
     if (position == 1) {
         return node.next;
     }
     node.next = node.next.next;
     return headNode;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值