List(CS61B学习记录)

  • 问题引入

上图中,赋给b海象的weight会改变a海象的weight,但x的赋值又不会改变y的赋值

Bits

要解释上图的问题,我们应该从Java的底层入手

相同的二进制编码,却因为数据类型不同,输出不同的值

变量的声明

基本类型

Java does not write anything into the reserved box when a variable is declared. In other words, there are no default values. As a result, the Java compiler prevents you from using a variable until after the box has been filled with bits using the = operator. For this reason, I have avoided showing any bits in the boxes in the figure above.

引用类型

When we declare a variable of any reference type (Walrus, Dog, Planet, array, etc.), Java allocates a box of 64 bits, no matter what type of object.

96位大于64位,这似乎有些矛盾:

在Java中:the 64 bit box contains not the data about the walrus, but instead the address of the Walrus in memory.

Gloden rule

练习

答案:B

解析:

  • 在调用方法(函数)时,doStuff方法中的int x与main方法中的int x 实际上处于两个不同的scope(调用方法时会new 一个scope,并将main方法中的x变量的位都传递给doStuff方法中的x变量,即值传递),所以x = x - 5实际上只作用于doStuff方法中的x,而不是main方法中的x。
  • 但对于引用类型来说,引用类型储存的是引用的地址,所以在进行值传递时传递的是对象的地址,所以doStuff方法中的int x与main方法中的walrus实际上指向相同的一个对象,这使得doStuff中执行的语句会作用于main方法中walrus指向的对象,所以反作用于main方法中的walrus

IntLists


使用递归求链表中元素的个数

java 复制代码
/** Return the size of the list using... recursion! */
public int size() {
    if (rest == null) {
        return 1;
    }
    return 1 + this.rest.size();
}

Exercise: You might wonder why we don't do something like if (this == null) return 0;. Why wouldn't this work?

Answer: Think about what happens when you call size. You are calling it on an object, for example L.size(). If L were null, then you would get a NullPointer error!

不使用递归求元素个数

java 复制代码
/** Return the size of the list using no recursion! */
public int iterativeSize() {
    IntList p = this;
    int totalSize = 0;
    while (p != null) {
        totalSize += 1;
        p = p.rest;
    }
    return totalSize;
}

求第n个元素

SLList

接下来我们对IntList进行改进,使链表看上去不那么naked

有了节点类,现在我们补充上链表类

java 复制代码
public class SLList {
    public IntNode first;

    public SLList(int x) {
        first = new IntNode(x, null);
    }
}

对比SLList和IntList,我们发现,在使用SLList时无需强调null

java 复制代码
IntList L1 = new IntList(5, null);
SLList L2  = new SLList(5);

addFirst() and getFirst()

java 复制代码
  /** Adds an item to the front of the list. */
    public void addFirst(int x) {
        first = new IntNode(x, first);
    }
    /** Retrieves the front item from the list. */
    public int getFirst() {
        return first.item;
}

private and nested class

java 复制代码
public class SLList {
    public class IntNode {
        public int item;
        public IntNode next;
        public IntNode(int i, IntNode n) {
            item = i;
            next = n;
        }
    }
    private IntNode first;

    public SLList(int x) {
        first = new IntNode(x, null);
    }
    /** Adds an item to the front of the list. */
    public void addFirst(int x) {
        first = new IntNode(x,first);
    }
    /** Retrieves the front item from the list. */
    public int getFirst() {
        return first.item;
    }
}

addLast() and Size()

java 复制代码
/** Adds an item to the end of the list. */
public void addLast(int x) {
    IntNode p = first;

    /* Advance p to the end of the list. */
    while (p.next != null) {
        p = p.next;
    }
    p.next = new IntNode(x, null);
}
java 复制代码
/** Returns the size of the list starting at IntNode p. */
private static int size(IntNode p) {
    if (p.next == null) {
        return 1;
    }

    return 1 + size(p.next);
}

优化低效的Size()方法

在改变链表的Size时直接记录下,就可以不需要在Size()方法中遍历链表了

java 复制代码
public class SLList {
    ... /* IntNode declaration omitted. */
    private IntNode first;
    private int size;

    public SLList(int x) {
        first = new IntNode(x, null);
        size = 1;
    }

    public void addFirst(int x) {
        first = new IntNode(x, first);
        size += 1;
    }

    public int size() {
        return size;
    }
    ...
}

空链表( The Empty List)

创建空链表很简单(对于SLList),但会导致addLast()方法报错

java 复制代码
public SLList() {
    first = null;
    size = 0;
}
java 复制代码
public void addLast(int x) {
    size += 1;
    IntNode p = first;
    while (p.next != null) {
        p = p.next;
    }

    p.next = new IntNode(x, null);
}

p指向null,故p.next会出现空指针异常

addLast()改进(使用分支)
java 复制代码
public void addLast(int x) {
    size += 1;

    if (first == null) {
        first = new IntNode(x, null);
        return;
    }

    IntNode p = first;
    while (p.next != null) {
        p = p.next;
    }

    p.next = new IntNode(x, null);
}
addLast()改进(更robust的做法)

对于存在很多特殊情况需要讨论 的数据结构,上面的方法就显得十分低效。

故我们需要考虑将其改进为一个具有普适性 的方法:将first改为sentinal.next
sentinal将会永远存在于链表的上位

java 复制代码
package lists.sslist;

public class SLList {
    public class IntNode {
        public int item;
        public IntNode next;
        public IntNode(int i, IntNode n) {
            item = i;
            next = n;
        }
    }

    private IntNode sentinel;
    private int size;

    public SLList() {
        sentinel = new IntNode(63,null);
        size = 0;
    }

    public SLList(int x) {
        sentinel = new IntNode(63,null);
        sentinel.next = new IntNode(x, null);
        size = 1;
    }

    /** Adds an item to the front of the list. */
    public void addFirst(int x) {
        sentinel.next = new IntNode(x, sentinel.next);
        size += 1;
    }

    /** Retrieves the front item from the list. */
    public int getFirst() {
        return sentinel.next.item;
    }

    /** Returns the number of items in the list. */
    public int size() {
        return size;
    }

    /** Adds an item to the end of the list. */
    public void addLast(int x) {
        IntNode p = sentinel;

        /* Advance p to the end of the list. */
        while (p.next != null) {
            p = p.next;
        }
        p.next = new IntNode(x, null);
    }

    /** Crashes when you call addLast on an empty SLList. Fix it. */
    public static void main(String[] args) {
        SLList x = new SLList();
        x.addLast(5);
    }
}
相关推荐
丶Darling.23 分钟前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
z樾2 小时前
Github界面学习
学习
道爷我悟了3 小时前
Vue入门-指令学习-v-html
vue.js·学习·html
计算机学姐4 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis
彤银浦4 小时前
python学习记录7
python·学习
少女忧4 小时前
51单片机学习第六课---B站UP主江协科技
科技·学习·51单片机
邓校长的编程课堂5 小时前
助力信息学奥赛-VisuAlgo:提升编程与算法学习的可视化工具
学习·算法
missmisslulu6 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
yunhuibin6 小时前
ffmpeg面向对象——拉流协议匹配机制探索
学习·ffmpeg
hengzhepa6 小时前
ElasticSearch备考 -- Search across cluster
学习·elasticsearch·搜索引擎·全文检索·es