【UCB CS 61B SP24】Lecture 3 - Lists 1: References, Recursion, and Lists学习笔记

本文开坑伯克利 CS 61B(算法与数据结构)2024年春季课程学习笔记,Lecture 1 & Lecture 2 的内容为课程介绍与 Java 基础,因此直接跳过。本文内容为介绍基本数据类型与引用数据类型的区别,以及手动实现整数列表。

1. 基本数据类型 & 引用数据类型

在 Java 中,所有数据类型可以分为两大类:Primitive Types(基本数据类型) 和 Reference Types(引用数据类型)。基本数据类型是 Java 语言内置的、最基础的数据类型,它们直接存储值,而不是对象的引用

Java 提供了8种基本数据类型,分别是:byteshortintlongfloatdoublecharboolean。基本数据类型直接存储值,存储在栈内存中,访问速度快,因为栈内存的读写效率高于堆内存。

引用数据类型是指存储在堆内存中的对象的引用。它们通过对象的引用(内存地址)来访问对象的实际数据。引用数据类型包括:类(Class)、接口(Interface)、数组(Array)、枚举(Enum)、包装类(Wrapper Classes)。

看下面这个例子:

package CS61B.Lecture3;public class PollQuestions {public static void main(String[] args) {Walrus a = new Walrus(1000, 8.3);Walrus b;b = a;b.weight = 5;System.out.println(a);  // Weight: 5, TuskSize: 8.30System.out.println(b);  // Weight: 5, TuskSize: 8.30int x = 5;int y;y = x;y = 2;System.out.println(x);  // 5System.out.println(y);  // 2}public static class Walrus {public int weight;public double tuskSize;public Walrus(int weight, double tuskSize) {this.weight = weight;this.tuskSize = tuskSize;}public String toString() {return String.format("Weight: %d, TuskSize: %.2f", weight, tuskSize);}}
}

对于基本数据类型,执行 y = x 实际上是将 x 在内存中所存放的值复制y,两个变量互相独立。

Walrus 类的对象为引用数据类型,当声明任何引用类型的变量时,无论对象类型是什么,Java 都精确地分配一个64位大小的空间,这些位可以设置为 null(全为零)或该类的特定实例的64位地址(由 new 返回)。

我们创建了一个 Walrus 对象,并将其引用赋值给变量 a。此时,a 指向堆内存中的一个 Walrus 对象,而之后又声明了一个变量 b,并将 a 的引用复制b。此时,ab 都指向同一个 Walrus 对象(内存地址相同)。换句话说,ab同一个对象的两个引用

通过 IDEA 的 Java Visualizer 插件进行调试可以直观地看到不同数据在内存中的情况:

在这里插入图片描述

对于函数的参数传递同样会完成复制值的操作,例如以下代码的 doStuff 方法接收的参数 w 执行了 w = walrus 操作,而 walrus 变量为一个 Walrus 类的对象地址,因此 w 接收到的是从 walrus 那复制过来的地址,而不像 x 接收到的是从 a 复制过来的值:

package CS61B.Lecture3;public class ParameterPassing {public static void main(String[] args) {Walrus walrus = new Walrus(3500, 10.5);int a = 9;doStuff(walrus, a);System.out.println(walrus);  // Weight: 2500, TuskSize: 10.50System.out.println(a);  // 9}public static void doStuff(Walrus w, int x) {w.weight -= 1000;x -= 5;}public static class Walrus {public int weight;public double tuskSize;public Walrus(int weight, double tuskSize) {this.weight = weight;this.tuskSize = tuskSize;}public String toString() {return String.format("Weight: %d, TuskSize: %.2f", weight, tuskSize);}}
}

2. 数组与列表

数组不是基本数据类型,因此也需要用 new 进行初始化:

int[] a = new int[]{0, 1, 2, 3}

数组的大小在创建时必须指定,并且一旦创建,其大小不能改变,数组的值存储在堆内存中,但数组变量(引用)存储在栈内存中,也就是上述代码中的变量 a

列表的大小可以动态变化,可以根据需要添加或删除元素,列表本身是一个对象,存储在堆内存中,其内部通过动态数组或其他数据结构(如链表)来存储元素。

我们先手动实现一个整数列表:

package CS61B.Lecture3;public class IntList {public int val;public IntList next;public IntList(int val) {this.val = val;this.next = null;}public static void main(String[] args) {IntList L = new IntList(5);L.next = new IntList(3);L.next.next = new IntList(10);while (L != null) {System.out.print(L.val + " ");L = L.next;}  // 5 3 10}
}

其可视化效果如下:

在这里插入图片描述

同样我们还能构建一个反向列表,即元素在首部插入:

package CS61B.Lecture3;public class IntList {public int val;public IntList next;public IntList(int val, IntList next) {this.val = val;this.next = next;}public static void main(String[] args) {IntList L = new IntList(5, null);L = new IntList(3, L);L = new IntList(10, L);while (L != null) {System.out.print(L.val + " ");L = L.next;}  // 10 3 5}
}

最后我们可以实现求解列表长度以及获取某个元素的方法:

package CS61B.Lecture3;public class IntList {public int val;public IntList next;public IntList(int val, IntList next) {this.val = val;this.next = next;}// 使用递归求解列表长度public int sizeRecursive() {if (this.next == null) {return 1;} else return 1 + this.next.sizeRecursive();}// 使用遍历求解列表长度public int sizeIterative() {int res = 0;IntList p = this;  // 创建一个指向当前地址的变量while (p != null) {res++;p = p.next;}return res;}// 使用递归求解列表第i个元素public int getVal(int i) {if (i >= this.sizeRecursive()) {System.out.println(String.format("Index %d is out of range!", i));return 0;}if (i == 0) return this.val;else return this.next.getVal(i - 1);}public static void main(String[] args) {IntList L = new IntList(5, null);L.next = new IntList(3, null);L.next.next = new IntList(10, null);System.out.println(L.sizeRecursive());  // 3System.out.println(L.sizeIterative());  // 3System.out.println(L.getVal(2));  // 10while (L != null) {System.out.print(L.val + " ");L = L.next;}  // 5 3 10}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/20984.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】fwrite函数用法介绍

目录 一、函数原型 二、参数解析 三、返回值 四、核心特性 五、案例代码 案例1:写入字符串到文件 案例2:写入整型数组到二进制文件 案例3:写入结构体数据 六、注意事项 一、函数原型 作用:将内存中的数据块以二进制形式…

WIN系统服务器如何修改远程端口?

在Windows服务器上修改远程桌面协议(RDP)的默认端口(3389)可以增强服务器的安全性,减少被恶意扫描和攻击的风险。以下是修改远程端口的详细步骤: --- ### **步骤 1:通过注册表修改远程端口** …

使用Termux将安卓手机变成随身AI服务器(page assist连接)

通过以下方法在安卓手机上运行 Ollama 及大模型,无需 Root 权限,具体方案如下: 通过 Termux 模拟 Linux 环境运行 核心工具: 安装 (安卓终端模拟器)()]。借助 proot-distro 工具安装 Linux 发行版&#xf…

【Prometheus】prometheus结合pushgateway实现脚本运行状态监控

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

《运维工程师如何利用DeepSeek实现智能运维:分级实战指南》

目录 智能运维革命:DeepSeek带来的范式转变DeepSeek核心运维能力全景解析分级实战场景与解决方案 3.1 初级工程师:自动化运维入门3.2 中级工程师:复杂系统诊断与优化3.3 高级工程师:架构级智能运维典型项目案例深度剖析 4.1 金融系统全链路监控体系构建4.2 电商大促资源弹性…

elementui中aria-hidden报错

浏览器检查的原因,不影响功能,但会在控制台报红 解决办法: 在对应元素设置display:none .el-radio__original {display: none !important;}

重构谷粒商城07:Git一小时快速起飞指南

重构谷粒商城07:Git一小时快速起飞指南 前言:这个系列将使用最前沿的cursor作为辅助编程工具,来快速开发一些基础的编程项目。目的是为了在真实项目中,帮助初级程序员快速进阶,以最快的速度,效率&#xff…

关于人工智能的学习方向应该怎么选择

目前AI-人工智能主流方向和应用场景的判断有哪些呢?学习方向与建议(根据自身情况而定)总结 人工智能-AI从2023年开始逐渐的在整个行业传播被大家所推崇,再根据这两年人工智能不断迭代更新,特别是DeepSeek的横空出世让国…

Huatuo热更新--如何使用

在安装完huatuo热更新插件后就要开始学习如何使用了。 1.创建主框渐Main 新建文件夹Main(可自定义),然后按下图创建文件,注意名称与文件夹名称保持一致 然后新建场景(Init场景),添加3个空物体…

DeepSeek 和 ChatGPT 在特定任务中的表现:逻辑推理与创意生成

🎁个人主页:我们的五年 🔍系列专栏:Linux网络编程 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 ​ Linux网络编程笔记: https://blog.cs…

车载音频配置(二)

目录 OEM 自定义的车载音频上下文 动态音频区配置 向前兼容性 Android 14 车载音频配置 在 Android 14 中,AAOS 引入了 OEM 插件服务,使你可以更主动地管理由车载音频服务监督的音频行为。 随着新的插件服务的引入,车载音频配置文件中添加了以下更改: • OEM 自定义的车…

【SQL】SQL多表查询

多表查询案例联系点击此处 🎄概念 一般我们说的多表查询都涉及外键和父子表之间的关系。比如一对多:一般前面指的是父表后面指的是子表。 ⭐分类 一对多(多对一) 多对多 一对一 ⭐一对多 📢案例:部门与员工的关系 📢关系&…

存储区域网络(SAN)管理

存储区域网络(Storage Area Network,SAN)采用网状通道(Fibre Channel ,简称FC)技术,通过FC交换机连接存储阵列和服务器主机,建立专用于数据存储的区域网络。SAN提供了一种与现有LAN连…

导出指定文件夹下的文件结构 工具模块-Python

python模块代码 import os import json import xml.etree.ElementTree as ET from typing import List, Optional, Dict, Union from pathlib import Path class DirectoryTreeExporter:def __init__(self,root_path: str,output_file: str,fmt: str txt,show_root: boo…

PyCharm Terminal 自动切换至虚拟环境

PyCharm 虚拟环境配置完毕后,打开终端,没有跟随虚拟环境切换,如图所示: 此时,需要手动将终端切换为 Command Prompt 模式 于是,自动切换至虚拟环境 每次手动切换,比较麻烦,可以单…

Vue 实现通过URL浏览器本地下载 PDF 和 图片

1、代码实现如下: 根据自己场景判断 PDF 和 图片,下载功能可按下面代码逻辑执行 const downloadFile async (item: any) > {try {let blobUrl: any;// PDF本地下载if (item.format pdf) {const response await fetch(item.url); // URL传递进入i…

【前端】使用WebStorm创建第一个项目

文章目录 前言一、步骤1、启动2、创建项目3、配置Node.js4、运行项目 二、Node.js介绍 前言 根据前面文章中记录的步骤,已经安装好了WebStorm开发软件,接下来我们就用这个IDE开发软件创建第一个项目。 一、步骤 1、启动 启动软件。 2、创建项目 新建…

遥感与GIS在滑坡、泥石流风险普查中的实践技术应用

原文>>> 遥感与GIS在滑坡、泥石流风险普查中的实践技术应用 我国是地质灾害多发国家,地质灾害的发生无论是对于地质环境还是人类生命财产的安全都会带来较大的威胁,因此需要开展地质灾害风险普查。利用遥感(RS)技术进行地…

EasyExcel 自定义头信息导出

需求:需要在导出 excel时,合并单元格自定义头信息(动态生成),然后才是字段列表头即导出数据。 EasyExcel - 使用table去写入:https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E4%BD%BF%E7%94%A8table%E…

QT异步编程之QMetaObject::invokeMethod

一、概述 1、QMetaObject::invokeMethod是Qt的一个功能强大的方法,它用于动态地调用一个对象地槽函数或成员函数。 2、这个方法允许你在运行时通过对象地元对象系统调用函数,而无需直接使用函数指针或其它静态机制。 3、元对象系统是一个基于C的扩展…