Heim  >  Artikel  >  Backend-Entwicklung  >  So implementieren Sie einen Liniensegmentbaum in PHP

So implementieren Sie einen Liniensegmentbaum in PHP

醉折花枝作酒筹
醉折花枝作酒筹nach vorne
2021-06-28 16:33:422025Durchsuche

Der Liniensegmentbaum ist ein binärer Suchbaum, ähnlich dem Intervallbaum. Er unterteilt ein Intervall in einige Einheitsintervalle, und jedes Einheitsintervall entspricht einem Blattknoten im Liniensegmentbaum. Im Folgenden erklärt Ihnen der Herausgeber, wie Sie Liniensegmentbäume in PHP implementieren. Sie können bei Bedarf darauf zurückgreifen.

So implementieren Sie einen Liniensegmentbaum in PHP

1. Funktionen

  • ist nicht unbedingt ein vollständiger Binärbaum

  • muss ein Binärbaum sein

  • Die Blattknoten speichern tatsächliche Werte und die Nicht-Blattknoten speichern benutzerdefinierte Inhalte

2. Zeitkomplexität

AbfrageO(logn)
Operation Zeitkomplexität
4 . Code

<?php
/**
 * content: 线段树(区间树)
 * create: 2020-11-12
 */

namespace HeapBundle;

use ArrayBundle\BaseArray;

class SegmentTreeHeap
{
    /**
     * 传入的数组对象
     * @var BaseArray 
     */
    protected $array;

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

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

    /**
     * 构建线段树
     * @param int $treeIndex
     * @param int $min
     * @param int $max
     * @throws \Exception
     */
    public function build(int $treeIndex, int $min, int $max)
    {
        // 如果线段区间的最小值和最小值相同,则表示为叶子结点
        if ($min == $max) {
            $this->tree[$treeIndex] = $this->array->get($max);
            return;
        }

        // 四舍五入取中间值  最大值减最小值然后除以2拿到中间值,并加上最小值
        $mid = floor(($max - $min) / 2) + $min;

        // 获取左儿子的索引值,并递归往下构建
        $leftIndex = $this->leftChildIndex($treeIndex);
        $this->build($leftIndex, $min, $mid);

        // 获取右儿子的索引值,并递归往下构建
        $rightIndex = $this->rightChildIndex($treeIndex);
        $this->build($rightIndex, $mid + 1, $max);

        // 非叶子结点的值保留的是它下面所有结点的相加值, 这里可以改为它下面结点的总和值
        $this->tree[$treeIndex] = $this->tree[$leftIndex] . &#39;+&#39; . $this->tree[$rightIndex];
    }

    /**
     * 打印线段树
     */
    public function varDump()
    {
        ksort($this->tree);
        print_r($this->tree);
    }

    /**
     * 获取线段树的长度
     * @return int
     */
    public function getSize(): int
    {
        return count($this->tree);
    }

    /**
     * 获取左儿子索引
     * @param int $parentIndex
     * @return int
     * @throws \Exception
     */
    public function leftChildIndex(int $parentIndex): int
    {
        if ($parentIndex < 0) throw new \Exception(&#39;父结点的索引不能小于0&#39;);
        return $parentIndex * 2 + 1;
    }

    /**
     * 获取右儿子索引
     * @param int $parentIndex
     * @return int
     * @throws \Exception
     */
    public function rightChildIndex(int $parentIndex): int
    {
        if ($parentIndex < 0) throw new \Exception(&#39;父结点的索引不能小于0&#39;);
        return $parentIndex * 2 + 2;
    }
}

5. Beispiel

<?php
require_once __DIR__ . &#39;/../../vendor/autoload.php&#39;;
$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
)
So implementieren Sie einen Liniensegmentbaum in PHPEmpfohlenes Lernen:

php-Video-Tutorial

Das obige ist der detaillierte Inhalt vonSo implementieren Sie einen Liniensegmentbaum in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen