0
0

【TypeScriptで学ぶデータ構造】リスト(片方向リスト)

Last updated at Posted at 2024-09-13

*pythonのリストではないです

リスト

複数存在しうる要素が、要素同士で要素の繋がりを示すデータ構造

片方向リスト(単方向リスト)

各要素が次の要素の位置を保持するデータ構造

要素のことをノードといい、ノードがどのノードにつながるのかを指し示す値をポインタというそうです。

具体的な例は履歴管理

ブラウザ等の操作履歴は前に戻ることもできるので若干異なりますが、前に戻ることなく、ただ履歴を管理したいというケースでは片方向リストが使われます。

実生活の具体的な例は、イベントのプログラム

イベントは最初からプログラムが決まっていて、それに沿って順番に進行されていきます。また次のイベント内容に進んだ場合、基本的には前に戻ることはないと思います。
この点が片方向リストと似ているかなと思いました。(厳密には、イベントで前の内容に戻ることはできるにはできてしまう)

片方向リストを再現したコード

List.ts
//リストのノードを表すクラス
class ListNode<T> {
  //ノードが保持するデータ
  data: T;          
  //次のノードへの参照(ポインタ!)
  next: ListNode<T> | null = null; 

  constructor(data: T) {
    this.data = data;
  }
}

//単方向リストを表すクラス
class LinkedList<T> {
  //リストの先頭を示す
  private head: ListNode<T> | null = null; 
  //リストのサイズを追跡
  private size: number = 0;               

  //リストに要素を追加するメソッド(今回は末尾に追加する機能のみ)
  add(data: T): void {
    const newNode = new ListNode(data);
    if (this.head === null) {
      this.head = newNode;
    } else {
      let current = this.head;
      while (current.next !== null) {
        current = current.next;
      }
      current.next = newNode;
    }
    this.size++;
  }

  //リストの指定されたインデックスにある要素を削除するメソッド
  removeAt(index: number): T | null {
    if (index < 0 || index >= this.size || this.head === null) {
      return null;
    }

    let current = this.head;
    if (index === 0) {
      this.head = current.next;
    } else {
      let previous: ListNode<T> | null = null;
      let i = 0;
      while (i < index) {
        previous = current;
        current = current.next!;
        i++;
      }
      if (previous !== null) {
        previous.next = current.next;
      }
    }
    this.size--;
    return current.data;
  }

  //リストの内容をコンソールに出力するメソッド
  printList(): void {
    let current = this.head;
    const result: T[] = [];
    while (current !== null) {
      result.push(current.data);
      current = current.next;
    }
    console.log(result.join(" -> "));
  }

  //リストのサイズを取得するメソッド
  getSize(): number {
    return this.size;
  }
}

//使用例
const list = new LinkedList<number>();
list.add(10);
list.add(20);
list.add(30);
list.printList(); // 10 -> 20 -> 30

console.log(`Size of the list: ${list.getSize()}`); // Size of the list: 3

//2番目の要素を削除
list.removeAt(1);
list.printList(); // 10 -> 30

console.log(`Size of the list: ${list.getSize()}`); // Size of the list: 2

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0