线性表(持续更新中)

线性表就是数据排成一条线的结构

常见的结构有:数组、栈、队列、链表

链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的

链表基础结构
public class ListNode {
    // 当前节点值
    int var;
    // 所指向下一个节点
    ListNode next;
    ListNode(int var) {
        this.var = var;
    }
}
构建基本列表
int[] arr = {1, 2, 3, 4, 5};
ListNode head = new ListNode(arr[0]);
ListNode tail = head;
for (int i = 1; i < arr.length; i ++) {
    tail.next = new ListNode(arr[i]);
    tail = tail.next;
}
实现反转链表

反转链表流程图

public static ListNode reverseLinkedList(ListNode node) {
    if (Objects.isNull(node)) { return null;}
    // 1 -> 2 -> 3 -> 4 -> 5
    // prev = 1
    // current = 2
    ListNode prev = node;
    ListNode current = prev.next;
    // 1  2 -> 3 -> 4 -> 5
    // prev = 1
    // current = 2
    prev.next = null;
    while (current != null) {
        // first time
        /*
        next = 3
        1 <- 2  3 < 4 <- 5
        prev = 2
        current = 3
         */
        // Second time
        /*
        next = 4
        1 <- 2 <- 3  4 <- 5
        prve = 3
        current = 4
         */
        // third time
        /*
        next = 5
        1 <- 2 <- 3 <- 4  5
        prve = 4
        current = 5
         */
        //fourth time
        /*
        next = null
        1 <- 2 <- 3 <- 4 <- 5
        prve = 5
        current = 5
         */
        ListNode next = current.next;
        current.next = prev;
        prev = current;
        current = next;
    }
    return prev;
}
反转指定节点链表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public static ListNode reverseBetweenLinkedList(ListNode head, int m, int n) {
    if (Objects.isNull(head) || m >= n) { return head;}
    // 创建一个虚拟节点
    ListNode dummy = new ListNode(-1);
    dummy.next = head;
    head = dummy;
    // 定位起始节点
    for (int i = 1; i < m; i++) {
        head = head.next;
    }
    ListNode prevM = head;
    ListNode mNode = prevM.next;
    ListNode nNode = mNode;
    ListNode postN = nNode.next;
    // 反转指定节点
    for (int i = m; i < n; i++) {
        ListNode next = postN.next;
        postN.next = nNode;
        nNode = postN;
        postN = next;
    }
    prevM.next = nNode;
    mNode.next = postN;
    return dummy.next;
}

小知识点:数组为什么从0开始

  1. 历史原因

语言出现顺序从早到晚C、Java、JavaScript。
C语言数组下标是从0开始->Java也是->JavaScript也是。
降低额外的学习和理解成本。

  1. 减少CPU指令运算

(1)下标从0开始:
数组寻址——arr[i] = base_address + i * type_size(1)
其中base_address为数组arr首地址,arr[0]就是偏移量为0的数组,即数组arr首地址;i为偏移量,type_size为数组类型字节数,比如int为32位,即4个字节。
(2)下标从1开始:
数组寻址——arr[i] = base_address + (i -1)* type_size(2)
比较两个计算公式可以发现公式(2)每次CPU寻址需要多一次 i-1的操作,即多了一次减法的指令运算。
对于数组这种基础数据结构,无论在哪种高级程序语言中,都是频繁间接(作为容器的基础数据结构,比如Java的ArrayList)或者直接被使用的,因此要尽量减少其消耗CPU资源。

  1. 原因三:物理内存的地址是从0开始的

计算机主存是多个连续字节大小的单元组成的数组,每个字节都对应唯一的物理地址,第一个字节的地址为0。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值