【问题标题】:how does this node class works in doubly linked list这个节点类如何在双向链表中工作
【发布时间】:2022-12-09 21:58:14
【问题描述】:

在 Node 类中,next 的类型为 Node 或 null。通过这个我们只能将 Node 或 null 分配给 next

class Node {
  value: any;
  next: Node | null;
  prev: Node | null;

  constructor(value: any) {
    this.value = value;
    this.next = null;
    this.prev = null;
  }
}

但我在推送功能中看到,在这一行“this.tail!.next = newNode;”我们只将 newNode 引用分配给 next 属性,这里 newNode 只是一个引用,它不会像我们在 Node 类中那样具有值,或 next 或 prev 值。

push(value: any) {
    const newNode = new Node(value);
    if (this.length === 0) {
      this.head = newNode;
      this.tail = newNode;
    } else {
      this.tail!.next = newNode;
      newNode.prev = this.tail;
      this.tail = newNode;
    }
    this.length++;
    return this;
  }

我真的无法理解,如何只给出一个类型为 Node 的 next 引用,而不是包含 value、next 和 prev 属性的 Node。

【问题讨论】:

  • 在 typescript(和 javascript)中,引用和值之间没有区别,就像在 C++ 中一样。每个对象都通过引用访问。声明aNode: Node与赋值aNode = new Node(...)完全兼容

标签: typescript data-structures linked-list nodes doubly-linked-list


【解决方案1】:

这里 newNode 只是一个引用,它不会像我们在 Node 类中那样具有值、下一个或上一个值。

在 TypeScript 中,对象始终作为引用处理。对于 Node 没有 struct 类型的变量,就像在 C 中那样。当在 TypeScript/JavaScript 中我们谈到“对象”时,推断我们处理的是引用。点运算符实际上对应于 C 中的 ->。C 中的点运算符(用于 struct 变量)在 TypeScript/JavaScript 中没有对应项,因为它没有此类类型化变量。

newNode 引用由构造函数初始化的对象,具有 valuenextprev 属性。

tail.next 属性确实分配了一个引用,这是预期的。

例如,假设我们已经有一个列表,其中一个节点的值为 1,那么我们可以这样描绘它:

 list
  ↓
┌───────────┐   ┌────────────┐
│ head: ───────►│ prev: null │
│ tail: ───────►│ value: 0   │
│ length: 1 │   │ next: null │
└───────────┘   └────────────┘

如果现在调用list.push(2),我们首先获取与new Node(2)一起运行的Node构造函数,它初始化对象的属性,并返回要分配给newNode的对象(引用):

 list
  ↓
┌───────────┐   ┌────────────┐
│ head: ───────►│ prev: null │
│ tail: ───────►│ value: 0   │
│ length: 1 │   │ next: null │
└───────────┘   └────────────┘

                ┌────────────┐
                │ prev: null │
                │ value: 2   │
                │ next: null │
                └────────────┘
                   ↑
                 newNode

那么this.tail!.next = newNode;将会复制该参考:

 list
  ↓
┌───────────┐   ┌────────────┐
│ head: ───────►│ prev: null │
│ tail: ───────►│ value: 0   │
│ length: 1 │   │ next: ┐    │
└───────────┘   └───────│────┘
                        ▼
                ┌────────────┐
                │ prev: null │
                │ value: 2   │
                │ next: null │
                └────────────┘
                   ↑
                 newNode

newNode.prev = this.tail; 负责相反方向的链接:

 list
  ↓
┌───────────┐   ┌────────────┐
│ head: ───────►│ prev: null │
│ tail: ───────►│ value: 0   │
│ length: 1 │   │ next: ┐    │
└───────────┘   └───────│────┘
                        ▼ ▲
                ┌─────────│──┐
                │ prev: ──┘  │
                │ value: 2   │
                │ next: null │
                └────────────┘
                   ↑
                 newNode

最后this.tail = newNode;this.length++会完成操作:

 list
  ↓
┌───────────┐   ┌────────────┐
│ head: ───────►│ prev: null │
│ tail: ──────┐ │ value: 0   │
│ length: 1 │ │ │ next: ┐    │
└───────────┘ │ └───────│────┘
              │         ▼ ▲
              │ ┌─────────│──┐
              └►│ prev: ──┘  │
                │ value: 2   │
                │ next: null │
                └────────────┘
                   ↑
                 newNode

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 2016-11-05
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多