>  기사  >  백엔드 개발  >  PHP에서 선분 트리를 구현하는 방법

PHP에서 선분 트리를 구현하는 방법

醉折花枝作酒筹
醉折花枝作酒筹앞으로
2021-06-28 16:33:422041검색

라인 세그먼트 트리는 간격 트리와 유사한 이진 검색 트리입니다. 간격을 일부 단위 간격으로 나누고 각 단위 간격은 선 세그먼트 트리의 리프 노드에 해당합니다. 아래에서 편집자는 PHP에서 선분 트리를 구현하는 방법을 공유합니다. 필요한 경우 참조할 수 있습니다.

PHP에서 선분 트리를 구현하는 방법

1. 기능

  • 은 반드시 완전한 이진 트리일 필요는 없습니다.

  • 는 정사각형 이진 트리여야 합니다.

  • 리프 노드는 실제 값을 저장하고, 리프가 아닌 노드는 사용자 정의된 콘텐츠를 저장합니다.

2. 시간 복잡도

작업시간 복잡도QueryO(logn)
3.

4 . PHP에서 선분 트리를 구현하는 방법

<?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. 예

<?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
)

추천 학습:

php 비디오 튜토리얼

위 내용은 PHP에서 선분 트리를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제