8. Data structure (PHP Implementation) — implementation of segment tree

Time:2022-1-14

1. Features

  • Not necessarily a complete binary tree

  • It must be a peaceful binary tree

  • Leaf nodes store actual values, while non leaf nodes store user-defined contents

2. Time complexity

operation Time complexity
query O(logn)

3. Diagram of line segment tree

8. Data structure (PHP Implementation) -- implementation of segment tree

4. Code

<?php
/**
 *Content: segment tree (inter area tree)
 * create: 2020-11-12
 */

namespace HeapBundle;

use ArrayBundle\BaseArray;

class SegmentTreeHeap
{
    /**
     *Passed in array object
     * @var BaseArray 
     */
    protected $array;

    /**
     *Array
     * @var array 
     */
    protected $tree = [];

    public function __construct(BaseArray $array)
    {
        $this->array = $array;
        $this->build(0, 0, $this->array->getSize() - 1);
    }

    /**
     *Build segment tree
     * @param int $treeIndex
     * @param int $min
     * @param int $max
     * @throws \Exception
     */
    public function build(int $treeIndex, int $min, int $max)
    {
        //If the minimum value of the segment interval is the same as the minimum value, it is represented as a leaf node
        if ($min == $max) {
            $this->tree[$treeIndex] = $this->array->get($max);
            return;
        }

        //Rounding takes the middle value, the maximum minus the minimum, then divides by 2 to get the middle value, and adds the minimum value
        $mid = floor(($max - $min) / 2) + $min;

        //Get the index value of the left son and build it recursively
        $leftIndex = $this->leftChildIndex($treeIndex);
        $this->build($leftIndex, $min, $mid);

        //Get the index value of the right son and build it recursively
        $rightIndex = $this->rightChildIndex($treeIndex);
        $this->build($rightIndex, $mid + 1, $max);

        //The value of a non leaf node retains the sum value of all nodes below it. Here, it can be changed to the sum value of the nodes below it
        $this->tree[$treeIndex] = $this->tree[$leftIndex] . '+' . $this->tree[$rightIndex];
    }

    /**
     *Print segment tree
     */
    public function varDump()
    {
        ksort($this->tree);
        print_r($this->tree);
    }

    /**
     *Gets the length of the segment tree
     * @return int
     */
    public function getSize(): int
    {
        return count($this->tree);
    }

    /**
     *Get left index
     * @param int $parentIndex
     * @return int
     * @throws \Exception
     */
    public function leftChildIndex(int $parentIndex): int
    {
        If ($parentindex < 0) throw new \ exception ('index of parent node cannot be less than 0 ');
        return $parentIndex * 2 + 1;
    }

    /**
     *Get right index
     * @param int $parentIndex
     * @return int
     * @throws \Exception
     */
    public function rightChildIndex(int $parentIndex): int
    {
        If ($parentindex < 0) throw new \ exception ('index of parent node cannot be less than 0 ');
        return $parentIndex * 2 + 2;
    }
}

5. Examples

<?php
require_once __DIR__ . '/../../vendor/autoload.php';
$array = new ArrayBundleBaseArray();
for ($i = 0; $i < 10; $i++) {
 $array->addLast($i + 10);
}
$heap = new HeapBundleSegmentTreeHeap($array);
$heap->varDump();
Array
(
    [0] => 10+11+12+13+14+15+16+17+18+19
    [1] => 10+11+12+13+14
    [2] => 15+16+17+18+19
    [3] => 10+11+12
    [4] => 13+14
    [5] => 15+16+17
    [6] => 18+19
    [7] => 10+11
    [8] => 12
    [9] => 13
    [10] => 14
    [11] => 15+16
    [12] => 17
    [13] => 18
    [14] => 19
    [15] => 10
    [16] => 11
    [23] => 15
    [24] => 16
)