Table des matières
Liste chaînée unidirectionnelle
Caractéristiques de la liste chaînée unidirectionnelle :
Plusieurs opérations principales dans la liste chaînée
Initialiser le nœud
Initialiser la liste chaînée unidirectionnelle
Créer un nœud
Insérer un nœud (après insertion dans le nœud principal)
Pointez head vers le nœud suivant (node.next) du nœud à supprimer
初始化双向链表
创建节点
插入节点((插入到头节点之后)
搜索节点
删除节点
双向链表整体代码
总结
Maison interface Web js tutoriel Introduction détaillée aux listes chaînées en JavaScript

Introduction détaillée aux listes chaînées en JavaScript

Jan 02, 2019 am 09:58 AM
javascript node.js 数据结构

Cet article vous apporte une introduction détaillée aux listes chaînées en JavaScript. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Listes et tableaux chaînés

Tout le monde a utilisé des tableaux en js. Les tableaux sont en fait une structure de stockage séquentielle de tables linéaires. Sa caractéristique est qu'il utilise un ensemble d'adresses. . Les cellules mémoire consécutives stockent les éléments de données les uns après les autres. Ses inconvénients sont également dus à ses caractéristiques. Par exemple, lors de la suppression ou de l'insertion d'un tableau, un grand nombre d'éléments peuvent devoir être déplacés.

Voici une simulation approximative de l'opération d'insertion du tableau :

    insert(arr, index, data){
        for(let i = index + 1; i <p>À partir du code ci-dessus, nous pouvons voir que l'insertion et la suppression du tableau peuvent être un O(n ) opération. Cela conduit à la structure de données de la liste chaînée. La liste chaînée ne nécessite pas que les éléments logiquement adjacents soient adjacents dans des emplacements physiques, elle n'a donc pas les inconvénients de la structure de stockage séquentielle. Bien sûr, elle perd également le caractère aléatoire de la liste chaînée. tableau dans un espace continu. Avantages de l'accès. </p><h3 id="Liste-chaînée-unidirectionnelle">Liste chaînée unidirectionnelle</h3><p><span class="img-wrap"><img src="/static/imghw/default1.png" data-src="https://img.php.cn//upload/image/880/877/695/1546394138978971.png" class="lazy" title="1546394138978971.png" alt="Introduction détaillée aux listes chaînées en JavaScript"></span></p><h4 id="Caractéristiques-de-la-liste-chaînée-unidirectionnelle">Caractéristiques de la liste chaînée unidirectionnelle : </h4>
Copier après la connexion
  • Utilisez-en un Organisez n'importe quel espace mémoire pour stocker des éléments de données (l'espace mémoire ici peut être continu ou discontinu)

  • Chaque nœud (nœud) se compose des données elles-mêmes et d'un pointeur vers les suivants les nœuds sont composés de

  • L'accès à l'intégralité de la liste chaînée doit commencer à partir du pointeur de tête, qui pointe vers le premier nœud

  • le dernier nœud Le pointeur pointe vers null (NULL)

Plusieurs opérations principales dans la liste chaînée

  • Créer un nœud

  • Insérer un nœud

  • Rechercher/Nœud de parcours

  • Supprimer un nœud

  • Fusionner

Initialiser le nœud

  • Le pointeur pointe vers null

  • Données de stockage

    class Node {
        constructor(key) {
            this.next = null;
            this.key = key;
        }
    }
Copier après la connexion

Initialiser la liste chaînée unidirectionnelle

  • Chaque liste chaînée a un pointeur de tête, pointant vers le premier nœud, s'il n'y a pas de nœud, il pointe vers NULL

    class List {
        constructor() {
            this.head = null;
        }
    }
Copier après la connexion

Créer un nœud

    static createNode(key) {
        return new createNode(key);
    }
Copier après la connexion

Laissez-moi vous expliquer ici, j'ai exposé une méthode statique pour créer le nœud, au lieu de l'encapsuler directement dans l'opération d'insertion, parce que j'ai l'impression que cette logique serait plus correcte. Créez une liste chaînée à partir de -> Créer un nœud -> Insérez le nœud dans la liste chaînée. Vous pouvez rencontrer des articles qui présentent un moyen d'utiliser directement un élément de données comme paramètre pour appeler l'opération d'insertion et de créer un nœud à l'intérieur de l'insertion.

Insérer un nœud (après insertion dans le nœud principal)

L'opération d'insertion nécessite uniquement d'ajuster le pointeur du nœud :

  • <.>head n'existe pas Pointe vers un nœud, indiquant que le nœud actuellement inséré est le premier

    • head pointe vers le nœud

    • la tête pointe vers le nouveau nœud

    Le pointeur du nouveau nœud pointe vers le nœud pointé par la tête d'origine
    • Rechercher le nœud

    • Lancer la recherche depuis la tête

    Lorsque la clé dans le nœud est trouvée pour être égal à la clé que vous souhaitez trouver, renvoyer le nœud
    insert(node) {
        // 如果head有指向的节点
        if(this.head){
           node.next = this.head;
        }else {
           node.next = null;
        }
        this.head = node;
    }
Copier après la connexion

    Supprimer le nœud
  • Il y a trois situations ici :

  • Le nœud à supprimer se trouve être le premier, qui est le nœud pointé par head

    find(key) {
        let node = this.head;
        while(node !== null && node.key !== key){
            node = node.next;
        }
        return node;
    }
Copier après la connexion

Pointez head vers le nœud suivant (node.next) du nœud à supprimer

  • Le nœud à supprimer est le dernier nœud

    • Rechercher le nœud précédent ( prevNode) du nœud à supprimer

    Pointez le pointeur dans prevNode sur NULL
    • Supprimez un nœud au milieu du list
    • Trouver le nœud précédent (prevNode) du nœud à supprimer

    Changer le pointeur dans prevNode Points vers le suivant nœud du nœud actuellement à supprimer
    • Le code de la liste chaînée unidirectionnelle globale

    • Liste double chaînée
    • Si vous comprenez la liste à sens unique présentée ci-dessus, alors la liste à double sens présentée ici est en fait presque la même.

    delete(node) {
        // 第一种情况
        if(node === this.head){
            this.head = node.next;
            return;
        }
        
        // 查找所要删除节点的上一个节点
        let prevNode = this.head;
        while (prevNode.next !== node) {
            prevNode = prevNode.next;
        }
        
        // 第二种情况
        if(node.next === null) {
            prevNode.next = null;
        }
        
        // 第三种情况
        if(node.next) {
            prevNode.next = node.next;
        }
    }
Copier après la connexion

class ListNode {
  constructor(key) {
    this.next = null;
    this.key = key;
  }
}

class List {
  constructor() {
    this.head = null;
    this.length = 0;
  }

  static createNode(key) {
    return new ListNode(key);
  }

  // 往头部插入数据
  insert(node) {
    // 如果head后面有指向的节点
    if (this.head) {
      node.next = this.head;
    } else {
      node.next = null;
    }
    this.head = node;
    this.length++;
  }

  find(key) {
    let node = this.head;
    while (node !== null && node.key !== key) {
      node = node.next;
    }
    return node;
  }

  delete(node) {
    if (this.length === 0) {
      throw 'node is undefined';
    }

    if (node === this.head) {
      this.head = node.next;
      this.length--;
      return;
    }

    let prevNode = this.head;

    while (prevNode.next !== node) {
      prevNode = prevNode.next;
    }

    if (node.next === null) {
      prevNode.next = null;
    }
    if (node.next) {
      prevNode.next = node.next;
    }
    this.length--;
  }
}
Copier après la connexion

À partir de l'image ci-dessus, vous pouvez clairement voir la différence entre une liste doublement chaînée et une liste simplement chaînée . La liste doublement chaînée comporte un pointeur supplémentaire pointant vers le nœud précédent.

Initialiser le nœud

Introduction détaillée aux listes chaînées en JavaScript

Pointeur vers le nœud précédent

  • 指向后一个节点的指针

  • 节点数据

  •     class ListNode {
            this.prev = null;
            this.next = null;
            this.key = key;
        }
    Copier après la connexion

    初始化双向链表

    • 头指针指向NULL

        class List {
            constructor(){
                this.head = null;
            }
        }
    Copier après la connexion

    创建节点

        static createNode(key){
            return new ListNode(key);
        }
    Copier après la connexion

    插入节点((插入到头节点之后)

    • 看上图中head后面的第一个节点可以知道,该节点的prev指向NULL

    • 节点的next指针指向后一个节点, 也就是当前头指针所指向的那个节点

    • 如果head后有节点,那么原本head后的节点的prev指向新插入的这个节点(因为是双向的嘛)

    • 最后将head指向新的节点

        insert(node) {
            node.prev = null;
            node.next = this.head;
            if(this.head){
                this.head.prev = node;
            }
            this.head = node;
        }
    Copier après la connexion

    搜索节点

    这里和单向节点一样,就直接贴代码了

      search(key) {
        let node = this.head;
        while (node !== null && node.key !== key) {
          node = node.next;
        }
        return node;
      }
    Copier après la connexion

    删除节点

    和之前单向链表一样,分三种情况去看:

    • 删除的是第一个节点

      • head指向所要删除节点的下一个节点

      • 下一个节点的prev指针指向所要删除节点的上一个节点

    • 删除的是中间的某个节点

      • 所要删除的前一个节点的next指向所要删除的下一个节点

      • 所要删除的下一个节点的prev指向所要删除的前一个节点

    • 删除的是最后一个节点

      • 要删除的节点的上一个节点的next指向null(也就是指向删除节点的next所指的地址)

    Introduction détaillée aux listes chaînées en JavaScript

        delete(node) {
            const {prev,next} = node;
            delete node.prev;
            delete node.next;
            if(node === this.head){
                this.head = next;
            }
            if(next){
                next.prev = prev;
            }
            if(prev){
                prev.next = next;
            }
        }
    Copier après la connexion

    双向链表整体代码

        class ListNode {
      constructor(key) {
        // 指向前一个节点
        this.prev = null;
        // 指向后一个节点
        this.next = null;
        // 节点的数据(或者用于查找的键)
        this.key = key;
      }
    }
    
    /**
     * 双向链表
     */
    class List {
      constructor() {
        this.head = null;
      }
    
      static createNode(key) {
        return new ListNode(key);
      }
    
      insert(node) {
        node.prev = null;
        node.next = this.head;
        if (this.head) {
          this.head.prev = node;
        }
        this.head = node;
      }
    
      search(key) {
        let node = this.head;
        while (node !== null && node.key !== key) {
          node = node.next;
        }
        return node;
      }
    
      delete(node) {
        const { prev, next } = node;
        delete node.prev;
        delete node.next;
    
        if (node === this.head) {
          this.head = next;
        }
    
        if (prev) {
          prev.next = next;
        }
        if (next) {
          next.prev = prev;
        }
      }
    }
    Copier après la connexion

    总结

    这里做一个小总结吧,可能有一部分人读到这里还不是特别的明白,我的建议是先好好看懂上面的单向链表。 其实只要你明白了链表的基础概念,就是有一个head,然后在有好多的节点(Node),然后用一个指针把他们串起来就好了,至于里面的插入操作也好,删除也好,其实都是在调整节点中指针的指向。


    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

    Outils d'IA chauds

    Undresser.AI Undress

    Undresser.AI Undress

    Application basée sur l'IA pour créer des photos de nu réalistes

    AI Clothes Remover

    AI Clothes Remover

    Outil d'IA en ligne pour supprimer les vêtements des photos.

    Undress AI Tool

    Undress AI Tool

    Images de déshabillage gratuites

    Clothoff.io

    Clothoff.io

    Dissolvant de vêtements AI

    AI Hentai Generator

    AI Hentai Generator

    Générez AI Hentai gratuitement.

    Article chaud

    R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
    1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Meilleurs paramètres graphiques
    1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
    Will R.E.P.O. Vous avez un jeu croisé?
    1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

    Outils chauds

    Bloc-notes++7.3.1

    Bloc-notes++7.3.1

    Éditeur de code facile à utiliser et gratuit

    SublimeText3 version chinoise

    SublimeText3 version chinoise

    Version chinoise, très simple à utiliser

    Envoyer Studio 13.0.1

    Envoyer Studio 13.0.1

    Puissant environnement de développement intégré PHP

    Dreamweaver CS6

    Dreamweaver CS6

    Outils de développement Web visuel

    SublimeText3 version Mac

    SublimeText3 version Mac

    Logiciel d'édition de code au niveau de Dieu (SublimeText3)

    Comparez des structures de données complexes à l'aide de la comparaison de fonctions Java Comparez des structures de données complexes à l'aide de la comparaison de fonctions Java Apr 19, 2024 pm 10:24 PM

    Lors de l'utilisation de structures de données complexes en Java, Comparator est utilisé pour fournir un mécanisme de comparaison flexible. Les étapes spécifiques comprennent : la définition d’une classe de comparaison et la réécriture de la méthode de comparaison pour définir la logique de comparaison. Créez une instance de comparaison. Utilisez la méthode Collections.sort, en transmettant les instances de collection et de comparateur.

    Structures de données et algorithmes Java : explication détaillée Structures de données et algorithmes Java : explication détaillée May 08, 2024 pm 10:12 PM

    Les structures de données et les algorithmes sont à la base du développement Java. Cet article explore en profondeur les structures de données clés (telles que les tableaux, les listes chaînées, les arbres, etc.) et les algorithmes (tels que le tri, la recherche, les algorithmes graphiques, etc.) en Java. Ces structures sont illustrées par des exemples pratiques, notamment l'utilisation de tableaux pour stocker les scores, de listes chaînées pour gérer les listes de courses, de piles pour implémenter la récursion, de files d'attente pour synchroniser les threads, ainsi que d'arbres et de tables de hachage pour une recherche et une authentification rapides. Comprendre ces concepts vous permet d'écrire du code Java efficace et maintenable.

    Compréhension approfondie des types de référence en langage Go Compréhension approfondie des types de référence en langage Go Feb 21, 2024 pm 11:36 PM

    Les types de référence sont un type de données spécial dans le langage Go. Leurs valeurs ne stockent pas directement les données elles-mêmes, mais l'adresse des données stockées. Dans le langage Go, les types de référence incluent des tranches, des cartes, des canaux et des pointeurs. Une compréhension approfondie des types de référence est cruciale pour comprendre les méthodes de gestion de la mémoire et de transfert de données du langage Go. Cet article combinera des exemples de code spécifiques pour présenter les caractéristiques et l'utilisation des types de référence dans le langage Go. 1. Tranches Les tranches sont l'un des types de référence les plus couramment utilisés dans le langage Go.

    Structure de données PHP : l'équilibre des arborescences AVL, maintenant une structure de données efficace et ordonnée Structure de données PHP : l'équilibre des arborescences AVL, maintenant une structure de données efficace et ordonnée Jun 03, 2024 am 09:58 AM

    L'arbre AVL est un arbre de recherche binaire équilibré qui garantit des opérations de données rapides et efficaces. Pour atteindre l'équilibre, il effectue des opérations de virage à gauche et à droite, en ajustant les sous-arbres qui violent l'équilibre. Les arbres AVL utilisent l'équilibrage de hauteur pour garantir que la hauteur de l'arbre est toujours petite par rapport au nombre de nœuds, réalisant ainsi des opérations de recherche de complexité temporelle logarithmique (O (logn)) et maintenant l'efficacité de la structure de données même sur de grands ensembles de données.

    Analyse complète du cadre de collecte Java : disséquer la structure des données et révéler le secret d'un stockage efficace Analyse complète du cadre de collecte Java : disséquer la structure des données et révéler le secret d'un stockage efficace Feb 23, 2024 am 10:49 AM

    Présentation de Java Collection Framework L'infrastructure de collection Java est une partie importante du langage de programmation Java. Elle fournit une série de bibliothèques de classes conteneur qui peuvent stocker et gérer des données. Ces bibliothèques de classes de conteneurs ont différentes structures de données pour répondre aux besoins de stockage et de traitement des données dans différents scénarios. L'avantage du framework de collection est qu'il fournit une interface unifiée, permettant aux développeurs d'exploiter différentes bibliothèques de classes de conteneurs de la même manière, réduisant ainsi la difficulté de développement. Structures de données de l'infrastructure de collection Java L'infrastructure de collection Java contient diverses structures de données, chacune ayant ses propres caractéristiques et scénarios applicables. Voici plusieurs structures de données courantes du cadre de collection Java : 1. Liste : Liste est une collection ordonnée qui permet de répéter des éléments. Li

    L'ère de l'IA de JS est arrivée ! L'ère de l'IA de JS est arrivée ! Apr 08, 2024 am 09:10 AM

    Introduction à JS-Torch JS-Torch est une bibliothèque JavaScript d'apprentissage en profondeur dont la syntaxe est très similaire à celle de PyTorch. Il contient un objet tensoriel entièrement fonctionnel (peut être utilisé avec des dégradés suivis), des couches et des fonctions d'apprentissage en profondeur et un moteur de différenciation automatique. JS-Torch convient à la recherche sur l'apprentissage profond en JavaScript et fournit de nombreux outils et fonctions pratiques pour accélérer le développement de l'apprentissage profond. Image PyTorch est un framework d'apprentissage profond open source développé et maintenu par l'équipe de recherche de Meta. Il fournit un riche ensemble d'outils et de bibliothèques pour créer et former des modèles de réseaux neuronaux. PyTorch est conçu pour être simple, flexible et facile à utiliser, et ses fonctionnalités de graphique de calcul dynamique font

    Comparaison de Golang et Node.js dans le développement back-end Comparaison de Golang et Node.js dans le développement back-end Jun 03, 2024 pm 02:31 PM

    Go et Node.js présentent des différences en termes de typage (fort/faible), de concurrence (goroutine/boucle d'événement) et de garbage collection (automatique/manuel). Go a un débit élevé et une faible latence, et convient aux backends à charge élevée ; Node.js est bon pour les E/S asynchrones et convient à une concurrence élevée et à des requêtes courtes. Les cas pratiques des deux incluent Kubernetes (Go), la connexion à une base de données (Node.js) et les applications Web (Go/Node.js). Le choix final dépend des besoins de l'application, des compétences de l'équipe et des préférences personnelles.

    Structures de données PHP SPL : injectez de la vitesse et de la flexibilité dans vos projets Structures de données PHP SPL : injectez de la vitesse et de la flexibilité dans vos projets Feb 19, 2024 pm 11:00 PM

    Présentation de la bibliothèque de structures de données PHPSPL La bibliothèque de structures de données PHPSPL (Standard PHP Library) contient un ensemble de classes et d'interfaces pour stocker et manipuler diverses structures de données. Ces structures de données comprennent des tableaux, des listes chaînées, des piles, des files d'attente et des ensembles, chacun fournissant un ensemble spécifique de méthodes et de propriétés pour manipuler les données. Tableaux En PHP, un tableau est une collection ordonnée qui stocke une séquence d'éléments. La classe de tableau SPL fournit des fonctions améliorées pour les tableaux PHP natifs, notamment le tri, le filtrage et le mappage. Voici un exemple d'utilisation de la classe array SPL : useSplArrayObject;$array=newArrayObject(["foo","bar","baz"]);$array

    See all articles