欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 【UCB CS 61B SP24】Lecture 3 - Lists 1: References, Recursion, and Lists学习笔记

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

2025/2/22 2:04:31 来源:https://blog.csdn.net/m0_51755720/article/details/145734104  浏览:    关键词:【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}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词