Table des matières
Liste chaînée circulaire
Liste chaînée double
Liste chaînée circulaire bidirectionnelle
Résumé
Maison développement back-end Problème PHP Existe-t-il d'autres formes de représentation des listes chaînées ?

Existe-t-il d'autres formes de représentation des listes chaînées ?

Jul 27, 2021 pm 05:52 PM
php

Dans le dernier article, nous avons déjà dit qu'en plus de la simple liste chaînée à sens unique, il existe plusieurs autres formes de listes chaînées. Bien entendu, il s’agit également d’une caractéristique majeure de la structure de liste chaînée, qui est très flexible et pratique. Pensons-y brièvement, si le prochain du dernier nœud pointe vers le premier nœud, cela formera un anneau, qui est une liste chaînée circulaire.

Si nous ajoutons un attribut prev à chaque nœud qui pointe vers le nœud précédent, alors la liste chaînée devient une liste doublement chaînée. Si nous faisons également en sorte que le nœud suivant du dernier nœud pointe vers le premier nœud et que le précédent du premier nœud pointe vers le dernier nœud en fonction de la liste chaînée bidirectionnelle, ne serait-ce pas une liste chaînée circulaire bidirectionnelle ? Regardons de plus près ci-dessous.

Liste chaînée circulaire

Comme mentionné ci-dessus, nous laissons le dernier nœud pointer vers le premier nœud, et la liste chaînée ainsi formée est une liste chaînée circulaire, comme le montre la figure ci-dessous :

Existe-t-il dautres formes de représentation des listes chaînées ?

À propos de opérations des listes chaînées circulaires Nous ne donnerons pas d'explication détaillée. En fait, la plupart du code est le même que celui d'une liste chaînée unidirectionnelle, mais vous devez faire attention à deux choses :

1. et les opérations d'insertion, faites attention à la direction du dernier nœud et au prochain du dernier nœud. Pointez vers le premier nœud

2 La condition pour juger si le parcours de la liste chaînée est terminé est item->next == head. C'est-à-dire que si le nœud suivant de ce nœud est le nœud principal, le parcours de la liste chaînée est terminé.

Liste chaînée double

La liste chaînée double ajoute un attribut à la classe LinkedList pour pointer vers le nœud précédent.

// 双向链表
class LinkedList
{
    public $data;

    public $prev;
    public $next;
}
Copier après la connexion

Existe-t-il dautres formes de représentation des listes chaînées ?

Ensuite, nous initialisons une liste doublement chaînée.

/**
 * 生成链表
 */
function createLinkedList()
{
    $list = new LinkedList();
    $list->data = null;
    $list->next = null;
    $list->prev = null; // ** 全部都初始化为 null **
    return $list;
}

/**
 * 初始化链表
 * @param array $data 链表中要保存的数据,这里以数组为参考
 * @return LinkedList 链表数据
 */
function Init(array $data)
{
    // 初始化
    $list = createLinkedList();
    $r = $list;
    foreach ($data as $key => $value) {
        $link = new LinkedList();
        $link->data = $value;
        $link->next = null;
        $r->next = $link;
        $link->prev = $r; // ** 增加上级指向 **
        $r = $link;
    }
    return $list;
}

$link = Init(range(1, 10));

var_dump($link);
var_dump($link->next->next->next->next);
// object(LinkedList)#5 (3) {
//     ["data"]=>
//     int(4)
//     ["prev"]=>
//     object(LinkedList)#4 (3) {
//       ["data"]=>
//       int(3)
//       ["prev"]=>
//       object(LinkedList)#3 (3) {
//         ["data"]=>
//         int(2)
//         ["prev"]=>
//         object(LinkedList)#2 (3) {
//           ["data"]=>
//           int(1)
//           ["prev"]=>
//           object(LinkedList)#1 (3) {
//             ["data"]=>
//             NULL
//             ["prev"]=>
//             NULL
//             ["next"]=>
//             *RECURSION*
//           }
//           ["next"]=>
//           *RECURSION*
//         }
//         ["next"]=>
//         *RECURSION*
//       }
//       ["next"]=>
//       *RECURSION*
//     }
//     ["next"]=>
//     object(LinkedList)#6 (3) {
//       ["data"]=>
//       int(5)
//       ["prev"]=>
//       *RECURSION*
//       ["next"]=>
//       object(LinkedList)#7 (3) {
//         ["data"]=>
//         int(6)
//         ["prev"]=>
//         *RECURSION*
//         ["next"]=>
//         object(LinkedList)#8 (3) {
//           ["data"]=>
//           int(7)
//           ["prev"]=>
//           *RECURSION*
//           ["next"]=>
//           object(LinkedList)#9 (3) {
//             ["data"]=>
//             int(8)
//             ["prev"]=>
//             *RECURSION*
//             ["next"]=>
//             object(LinkedList)#10 (3) {
//               ["data"]=>
//               int(9)
//               ["prev"]=>
//               *RECURSION*
//               ["next"]=>
//               object(LinkedList)#11 (3) {
//                 ["data"]=>
//                 int(10)
//                 ["prev"]=>
//                 *RECURSION*
//                 ["next"]=>
//                 NULL
//               }
//             }
//           }
//         }
//       }
//     }
//   }

echo $link->next->next->next->next->data, PHP_EOL; // 4
echo $link->next->next->next->next->prev->data, PHP_EOL; // 3
Copier après la connexion

On peut voir que la différence avec la liste chaînée unidirectionnelle est qu'il y a plus d'opérations sur l'attribut prev. C’est relativement facile à comprendre ici. L'impression directe de la liste chaînée affichera beaucoup de contenu *RECURSION*, qui est un mécanisme de protection de sortie de PHP. Cette marque indique que la variable d'attribut actuelle a un type récursif.

/**
 * 链表指定位置插入元素
 * @param LinkedList $list 链表数据
 * @param int $i 位置
 * @param mixed $data 数据
 */
function Insert(LinkedList &$list, int $i, $data)
{
    $j = 0;
    $item = $list;
    // 遍历链表,找指定位置的前一个位置
    while ($j < $i - 1) {
        $item = $item->next;
        $j++;
    }

    // 如果 item 不存在或者 $i > n+1 或者 $i < 0
    if ($item == null || $j > $i - 1) {
        return false;
    }

    // 创建一个新节点
    $s = new LinkedList();
    $s->data = $data;

    // 新创建节点的下一个节点指向原 i-1 节点的下一跳节点,也就是当前的 i 节点
    $s->next = $item->next;

    // ** 增加当前新创建的节点的上级指向 **
    $s->prev = $item;

    // 将 i-1 节点的下一跳节点指向 s ,完成将 s 插入指定的 i 位置,并让原来的 i 位置元素变成 i+1 位置
    $item->next = $s;

    // ** 将下级节点的 prev 指向新创建的这个节点 **
    $s->next->prev = $s;

    return true;
}
Copier après la connexion

L'insertion de la liste chaînée ajoute en fait deux lignes de code. L'une est le pointeur vers le supérieur du nœud actuellement nouvellement créé, c'est-à-dire que le supérieur de ce nouveau nœud est désigné comme nœuds i-1. L'autre consiste à remplacer le pointeur supérieur du nœud de position i d'origine par le nœud nouvellement créé.

/**
 * 删除链表指定位置元素
 * @param LinkedList $list 链表数据
 * @param int $i 位置
 */
function Delete(LinkedList &$list, int $i)
{
    $j = 0;
    $item = $list;
    // 遍历链表,找指定位置的前一个位置
    while ($j < $i - 1) {
        $item = $item->next;
        $j++;
    }
    // 如果 item 不存在或者 $i > n+1 或者 $i < 0
    if ($item == null || $j > $i - 1) {
        return false;
    }

    // 使用一个临时节点保存当前节点信息,$item 是第 i-1 个节点,所以 $item->next 就是我们要找到的当前这个 i 节点
    $temp = $item->next;
    // 让当前节点,也就是目标节点的上一个节点, i-1 的这个节点的下一跳(原来的 i 位置的节点)变成原来 i 位置节点的下一跳 next 节点,让i位置的节点脱离链条
    $item->next = $temp->next;

    // ** 让目标下一个节点的上级指针指向当前这个节点 **
    $temp->next->prev = $item;

    return true;
}
Copier après la connexion

Semblable à l'opération de nœud d'insertion, l'opération de nœud de suppression change non seulement le pointage du nœud suivant des données du nœud de position i-1 vers le pointage du nœud de niveau suivant du nœud i, mais change également le nœud de niveau suivant de i Le nœud supérieur du nœud pointe vers le nœud i-1.

En fait, la définition et le fonctionnement d'une liste doublement chaînée ne sont pas très différents de ceux d'une liste chaînée unidirectionnelle, c'est juste qu'il y a un précédent supplémentaire pour pointer vers le nœud de niveau supérieur. c'est juste plus d'opérations sur l'attribut précédent. Alors, quels avantages apporte ce pointeur extra supérieur ? Lors du parcours de la liste chaînée, nous utilisons prev pour avoir une méthode de parcours supplémentaire, qui consiste à parcourir la liste chaînée en sens inverse. Lors de la recherche d'un certain élément, nous pouvons rechercher dans deux directions en même temps, et l'efficacité est immédiatement doublée. La complexité temporelle originale de O(n) peut instantanément devenir une complexité temporelle O(n/2).

Liste chaînée circulaire bidirectionnelle

Enfin, nous présenterons brièvement la liste chaînée circulaire bidirectionnelle. Comme son nom l'indique, il ajoute le concept de liste chaînée circulaire à une liste doublement chaînée. Laissez le prochain du dernier nœud pointer vers le nœud principal et laissez le précédent du nœud principal pointer vers le dernier nœud. C'est facile à dire mais c'est en réalité beaucoup plus compliqué à mettre en œuvre, car il faut non seulement faire attention au problème de pointage des nœuds subordonnés du dernier nœud, mais aussi au problème du pointage supérieur du nœud principal. Nous ne ferons donc pas trop de démonstration de code ici. La chose la plus importante est que lors de l'insertion et de la suppression de nœuds de tête et de queue, vous devez prêter plus d'attention au pointage de leurs nœuds supérieurs et inférieurs.

Existe-t-il dautres formes de représentation des listes chaînées ?

Résumé

Avez-vous soudainement découvert un nouveau monde ? Il existe de nombreuses formes de listes chaînées. Bien sûr, ce n'est pas encore fini. Nous avons encore une liste réticulée très haut de gamme à aborder. Cependant, en fait, la liste réticulée ne fait qu'ajouter des attributs de pointage supplémentaires. Le champ de données de base est toujours le même. . En fait, la liste chaînée unidirectionnelle la plus courante, qui est celle présentée en détail dans l'article précédent, est le véritable objectif de l'apprentissage des listes chaînées.

Donc, vous n'avez pas besoin d'être anxieux ou de paniquer. Si vous maîtrisez la liste chaînée à sens unique ordinaire, vous pouvez tuer la plupart des gens en un instant. Mais qu'en est-il de ces choses que vous avez apprises aujourd'hui ? Si vous pouvez le maîtriser, vous pouvez au moins le connaître. La chose la plus importante dans la vie est d'être heureux. Ne vous forcez pas, vous deviendrez soit un dragon, soit un ver. Reconnaissez votre situation actuelle et vos capacités. C'est la chose la plus importante.

关于线性表的内容到此为止。物理结构的存储问题就是这样了,接下来我们就要逻辑结构的世界了。也是从最简单的开始,那就是栈和队列,不要怕,它们和 树、图 比起来真的是洒洒水啦!!

测试代码:

https://github.com/zhangyue0503/Data-structure-and-algorithm/blob/master/2.线性表/source/2.4%20链表的其它形式.php
Copier après la connexion

推荐学习:php视频教程

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)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines 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)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

Discuter de CakePHP Discuter de CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP est un framework open source pour PHP. Il vise à faciliter grandement le développement, le déploiement et la maintenance d'applications. CakePHP est basé sur une architecture de type MVC à la fois puissante et facile à appréhender. Modèles, vues et contrôleurs gu

Téléchargement de fichiers CakePHP Téléchargement de fichiers CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler sur le téléchargement de fichiers, nous allons utiliser l'assistant de formulaire. Voici un exemple de téléchargement de fichiers.

CakePHP créant des validateurs CakePHP créant des validateurs Sep 10, 2024 pm 05:26 PM

Le validateur peut être créé en ajoutant les deux lignes suivantes dans le contrôleur.

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

Guide rapide CakePHP Guide rapide CakePHP Sep 10, 2024 pm 05:27 PM

CakePHP est un framework MVC open source. Cela facilite grandement le développement, le déploiement et la maintenance des applications. CakePHP dispose d'un certain nombre de bibliothèques pour réduire la surcharge des tâches les plus courantes.

Comment analysez-vous et traitez-vous HTML / XML dans PHP? Comment analysez-vous et traitez-vous HTML / XML dans PHP? Feb 07, 2025 am 11:57 AM

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

See all articles