在php中实现链表

时间:2010-09-02 20:28:21

标签: php linked-list

我应该如何在PHP中实现链接列表? PHP中是否内置了一个实现?

我需要做很多插入和删除操作,同时我需要保留顺序。

我只想使用没有任何特殊扩展名的PHP。

8 个答案:

答案 0 :(得分:19)

SplDoublyLinkedList。这也没关系吗?

答案 1 :(得分:18)

以下是PHP中的链接列表实现:http://www.codediesel.com/php/linked-list-in-php/,可以在PHP中添加,删除,反向和清空链接列表。

<?php
class ListNode
{
    public $data;
    public $next;
    function __construct($data)
    {
        $this->data = $data;
        $this->next = NULL;
    }

    function readNode()
    {
        return $this->data;
    }
}

class LinkList
{
    private $firstNode;
    private $lastNode;
    private $count;

    function __construct()
    {
        $this->firstNode = NULL;
        $this->lastNode = NULL;
        $this->count = 0;
    }

    //insertion at the start of linklist
    public function insertFirst($data)
    {
        $link = new ListNode($data);
        $link->next = $this->firstNode;
        $this->firstNode = &$link;

        /* If this is the first node inserted in the list
           then set the lastNode pointer to it.
        */
        if($this->lastNode == NULL)
            $this->lastNode = &$link;
            $this->count++;
    }


    //displaying all nodes of linklist
    public function readList()
    {
        $listData = array();
        $current = $this->firstNode;
        while($current != NULL)
        {
            array_push($listData, $current->readNode());
            $current = $current->next;
        }
        foreach($listData as $v){
            echo $v." ";
        }
    }

    //reversing all nodes of linklist
    public function reverseList()
    {
        if($this->firstNode != NULL)
        {
            if($this->firstNode->next != NULL)
            {
                $current = $this->firstNode;
                $new = NULL;

                while ($current != NULL)
                {
                    $temp = $current->next;
                    $current->next = $new;
                    $new = $current;
                    $current = $temp;
                }
                $this->firstNode = $new;
            }
        }
    }



    //deleting a node from linklist $key is the value you want to delete
    public function deleteNode($key)
    {
        $current = $this->firstNode;
        $previous = $this->firstNode;

        while($current->data != $key)
        {
            if($current->next == NULL)
                return NULL;
            else
            {
                $previous = $current;
                $current = $current->next;
            }
        }

        if($current == $this->firstNode)
         {
              if($this->count == 1)
               {
                  $this->lastNode = $this->firstNode;
               }
               $this->firstNode = $this->firstNode->next;
        }
        else
        {
            if($this->lastNode == $current)
            {
                 $this->lastNode = $previous;
             }
            $previous->next = $current->next;
        }
        $this->count--;  
    }


       //empty linklist
    public function emptyList()
    {
        $this->firstNode == NULL;

    }


    //insertion at index

    public function insert($NewItem,$key){
        if($key == 0){
        $this->insertFirst($NewItem);
    }
    else{
        $link = new ListNode($NewItem);
        $current = $this->firstNode;
        $previous = $this->firstNode;

        for($i=0;$i<$key;$i++)
        {       
                $previous = $current;
                $current = $current->next;
        }

           $previous->next = $link;
           $link->next = $current; 
           $this->count++;
    }

    }   
}

$obj = new LinkList();
$obj->insertFirst($value);
$obj->insert($value,$key); // at any index
$obj->deleteNode($value);
$obj->readList();

答案 2 :(得分:4)

这是php中的代码,它将实现Linked List,只有头节点的引用,即第一个节点,然后你先添加,删除一个键,并在列表中维护键的代码。

<?php

/**
 * Class Node
 */
class Node
{
    public $data;
    public $next;

    public function __construct($item)
    {
        $this->data = $item;
        $this->next = null;
    }
}

/**
 * Class LinkList
 */
class LinkList
{
    public $head = null;

    private static $count = 0;

    /**
     * @return int
     */
    public function GetCount()
    {
        return self::$count;
    }

    /**
     * @param mixed $item
     */
    public function InsertAtFist($item) {
        if ($this->head == null) {
            $this->head = new Node($item);
        } else {
            $temp = new Node($item);

            $temp->next = $this->head;

            $this->head = $temp;
        }

        self::$count++;
    }

    /**
     * @param mixed $item
     */
    public function InsertAtLast($item) {
        if ($this->head == null) {
            $this->head = new Node($item);
        } else {
            /** @var Node $current */
            $current = $this->head;
            while ($current->next != null)
            {
                $current = $current->next;
            }

            $current->next = new Node($item);
        }

        self::$count++;
    }

    /**
     * Delete the node which value matched with provided key
     * @param $key
     */
    public function Delete($key)
    {
        /** @var Node $current */
        $current = $previous = $this->head;

        while($current->data != $key) {
            $previous = $current;
            $current = $current->next;
        }

        // For the first node
        if ($current == $previous) {
            $this->head = $current->next;
        }

        $previous->next = $current->next;

        self::$count--;
    }

    /**
     * Print the link list as string like 1->3-> ...
     */
    public function PrintAsList()
    {
        $items = [];
        /** @var Node $current */
        $current = $this->head;
        while($current != null) {
            array_push($items, $current->data);
            $current = $current->next;
        }

        $str = '';
        foreach($items as $item)
        {
            $str .= $item . '->';
        }

        echo $str;

        echo PHP_EOL;
    }
}

$ll = new LinkList();

$ll->InsertAtLast('KP');
$ll->InsertAtLast(45);
$ll->InsertAtFist(11);
$ll->InsertAtLast('FE');
$ll->InsertAtFist('LE');
$ll->InsertAtFist(100);
$ll->InsertAtFist(199);
$ll->InsertAtLast(500);

$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;
$ll->Delete(45);
$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;
$ll->Delete(500);
$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;
$ll->Delete(100);
$ll->PrintAsList();
echo 'Total elements ' . $ll->GetCount();
echo PHP_EOL;

代码输出为:

$ php LinkList.php
199->100->LE->11->KP->45->FE->500->
Total elements 8
199->100->LE->11->KP->FE->500->
Total elements 7
199->100->LE->11->KP->FE->
Total elements 6
199->LE->11->KP->FE->
Total elements 5

答案 3 :(得分:2)

这是使用元素数组的另一个链表实现。 add函数保持元素排序。

watchOS

输出结果为:

-0-2-3-4-5-7-10

-0-2-4-5-7-10

-2-4-5-7-10

答案 4 :(得分:0)

我还试图编写一个程序来在PHP中创建一个链表。这是我写的,它对我有用。我希望回答这个问题很有帮助。

Created a php file. Name: LinkedList.php
{code}
<?php

require_once (__DIR__ . "/LinkedListNodeClass.php");

$node_1 = new Node();
Node::createNode($node_1, 5);
echo "\n Node 1 is created.";

$head = &$node_1;
echo "\n Head is intialized with Node 1.";

$node_2 = new Node();
Node::createNode($node_2, 1);
echo "\n Node 2 is created.";

Node::insertNodeInLinkedList($head, $node_2);

$node_3 = new Node();
Node::createNode($node_3, 11);
echo "\n Node 3 is created.";

Node::insertNodeInLinkedList($head, $node_3);

$node_4 = new Node();
Node::createNode($node_4, 51);
echo "\n Node 4 is created.";

Node::insertNodeInLinkedList($head, $node_4);

$node_5 = new Node();
Node::createNode($node_5, 78);
echo "\n Node 5 is created.";

Node::insertNodeInLinkedList($head, $node_5);

$node_6 = new Node();
Node::createNode($node_6, 34);
echo "\n Node 6 is created.";

Node::insertNodeInLinkedList($head, $node_6);

$node_7 = new Node();
Node::createNode($node_7, 99);
echo "\n Node 7 is created.";

Node::insertNodeInHeadOfLinkedList($head, $node_7);

$node_8 = new Node();
Node::createNode($node_8, 67);
echo "\n Node 8 is created.";

Node::insertNodeInHeadOfLinkedList($head, $node_8);

$node_9 = new Node();
Node::createNode($node_9, 101);
echo "\n Node 9 is created.";

Node::insertNodeAfterAPositionInLinkedList($head, 5, $node_9);

$node_10 = new Node();
Node::createNode($node_10, 25);
echo "\n Node 10 is created.";

Node::insertNodeAfterAPositionInLinkedList($head, 2, $node_10);

echo "\n Displaying the linked list: \n";
Node::displayLinkedList($head);

?>
{code}

This file is calling a class to create, insert and display nodes in linked list. Name: LinkedListNodeClass.php
{code}
<?php

class Node {
  private $data;
  private $next;

  public function __construct() {
    //does nothing...
  }

  //Creates a node
  public function createNode($obj, $value) {
    $obj->data = $value;
    $obj->next = NULL;
  }    

  //Inserts a created node in the end of a linked list
  public function insertNodeInLinkedList($head, &$newNode) {
    $node = $head;
    while($node->next != NULL){
      $node = $node->next;
    }
    $node->next = $newNode;
  }

  //Inserts a created node in the start of a linked list
  public function insertNodeInHeadOfLinkedList(&$head, &$newNode) {
    $top = $head;
    $newNode->next = $top;
    $head = $newNode;
  }

  //Inserts a created node after a position of a linked list
  public function insertNodeAfterAPositionInLinkedList($head, $position, &$newNode) {
    $node = $head;
    $counter = 1;
    while ($counter < $position){
      $node = $node->next;
      $counter++;
    }
    $newNode->next = $node->next;
    $node->next = $newNode;
  }

  //Displays the Linked List
  public function displayLinkedList($head) {
    $node = $head;
    print($node->data); echo "\t";
    while($node->next != NULL){
      $node = $node->next;
      print($node->data); echo "\t";
    }
  }
}

?>
{code}

答案 5 :(得分:0)

如果不认为大多数人都了解链接列表是什么。基本思想是您希望保持数据的有序组织,以便您可以使用当前节点访问上一个和下一个节点。其他功能,如添加,删除,插入,头等都是糖,虽然是必要的。我认为SPL套件确实涵盖了很多。问题是我需要PHP 5.2.9类。我猜我自己实施它。

答案 6 :(得分:0)

仅需澄清,使用PHP数组在PHP中实现链接列表可能不是一个好主意,因为PHP数组是幕后的哈希表(而不是简单的低级数组)。同时,您没有获得指针的优势。

相反,您可以使用扩展实现PHP的链表 之类的数据结构,这意味着您正在 C 中实现数据结构PHP。

Spl数据结构是一个示例,另一个示例是php-ds扩展,特别是在链表的情况下,您可以使用以下命令:https://www.php.net/manual/en/class.ds-sequence.php

序列ADT是列表ADT和矢量ADT的统一,因此您可以将序列ADT实现的数据结构用作列表。

希望这可以帮助某人明智地选择。

答案 7 :(得分:-1)

// Here's a basic implementation of SplDoublyLinkedList using PHP.
$splDoubleLinkedList = new SplDoublyLinkedList();
$splDoubleLinkedList->push('a');
$splDoubleLinkedList->push('3');
$splDoubleLinkedList->push('v');
$splDoubleLinkedList->push('1');
$splDoubleLinkedList->push('p');
// $splDoubleLinkedList->unshift('10');
// $splDoubleLinkedList->pop();
$splDoubleLinkedList->add(3, 3.0);
// First of all, we need to rewind list.
$splDoubleLinkedList->rewind();
// Use while, check if the list has valid node.
while($splDoubleLinkedList->valid()){
  // Print current node's value.
   echo $splDoubleLinkedList->current()."\n";
 // Turn the cursor to next node.
 $splDoubleLinkedList->next();
}