K-dimensionellt träd | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Sorts | Flerdimensionellt träd Binärt sökträd | |||||||||||||||
Uppfinningens år | 1975 | |||||||||||||||
Författare | Jon Bentley | |||||||||||||||
Komplexitet i O-symboler | ||||||||||||||||
|
Ett k -d-träd ( eng. kd-träd , förkortning för k-dimensionellt träd ) är enrymduppdelad datastruktur för att ordna punkter i ett k - dimensionellt utrymme . k -d-träd används för vissa applikationer såsom flerdimensionell nyckelrymdssökning (avståndssökning och närmaste grannesökning ). k -d-träd är en speciell typ av binära sökträd .
Ett K-dimensionellt träd är ett obalanserat sökträd för att lagra punkter från . Den erbjuder en R-trädliknande förmåga att söka inom ett givet intervall av nycklar. Till nackdel för frågans enkelhet, minneskrav istället för .
Det finns homogena och icke-homogena kd-träd. I homogena kd-träd lagrar varje nod en post . I den heterogena varianten innehåller interna noder endast nycklar, blad innehåller länkar till poster.
I ett icke-homogent kd-träd med ett dimensionellt hyperplan parallellt med axeln vid punkten . För roten måste du dela upp punkterna genom hyperplanet i två uppsättningar punkter som är så stora som möjligt och skriva till roten, till vänster om detta, alla punkter för vilka är lagrade , till höger, de för vilka . För det vänstra underträdet behöver man dela upp punkterna igen i ett nytt "delat plan" och lagras i den interna noden. Till vänster om detta, alla punkter för vilka . Detta fortsätter rekursivt över alla utrymmen. Sedan börjar allt igen från första utrymmet tills varje punkt tydligt kan identifieras genom hyperplanet.
kd-träd kan byggas in . En intervallsökning kan utföras i , varvid anger storleken på svaret. Minneskravet för själva trädet är begränsat .
Trädstruktur som beskrivs i C++ :
constexprint N = 10 ; _ // antal tangentsteg struct Item { // item structure int key [ N ]; // array av nycklar som definierar elementet char * info ; // elementinformation }; struct Node { // trädnodsstruktur Item i ; // element Nod * vänster ; // vänster underträd Nod * höger ; // höger underträd }Trädets struktur kan variera beroende på detaljerna i implementeringen av algoritmen . Till exempel kan en nod innehålla en array snarare än ett enda element, vilket förbättrar sökeffektiviteten.
ElementsökningsanalysUppenbarligen är det minsta antalet visade element , och det maximala antalet visade element är , där är trädets höjd. Det återstår att beräkna det genomsnittliga antalet visade objekt .
är det givna elementet.
Låt oss överväga fallet . Hittade element kan vara:
och så vidare för varje knappsats. I det här fallet är den genomsnittliga söklängden på ett utrymme:
.Medelvärdet beräknas med formeln:
Det återstår att hitta sannolikheten . Det är lika med , där är antalet ärenden, när och är det totala antalet ärenden. Det är inte svårt att gissa vad .
Vi ersätter detta med formeln för medelvärdet:
,det vill säga var är höjden på trädet.
Om vi går från trädets höjd till antalet element, då:
, där är antalet element i noden.
Av detta kan vi dra slutsatsen att ju fler element som kommer att finnas i noden, desto snabbare blir trädsökningen, eftersom trädets höjd förblir minimal, men du bör inte lagra ett stort antal element i noden, eftersom med denna metod kan hela trädet urarta till en normal array eller lista.
Att lägga till element sker på exakt samma sätt som i ett vanligt binärt sökträd , med den enda skillnaden att varje nivå i trädet också bestäms av det utrymme som det tillhör.
Trädprogressionsalgoritm:
för ( int i = 0 ; träd ; i ++ ) // i är mellanslagsnumret if ( träd -> x [ i ] < träd -> t ) // t är medianträdet = träd - > vänster ; // flytta till vänster underträd else träd = träd -> höger ; // flytta till höger underträdTillägget utförs efter , där är trädets höjd.
När du tar bort trädelement kan flera situationer uppstå:
Ibland löses processen att ta bort en nod genom att modifiera kd-trädet. Till exempel, om vår nod innehåller en array av element, när hela arrayen raderas, finns trädnoden kvar, men nya element skrivs inte längre där.
Sökningen baseras på normal trädnedstigning, där varje nod kontrolleras för ett intervall. Om medianerna för en nod är mindre än eller större än ett givet område i ett givet utrymme, så går övergången längre längs en av trädets grenar. Om medianen för noden är helt inom det givna intervallet måste båda underträden besökas.
Algoritm Z - trädnod _ [( x_0_min , x_1_min , x_2_min ,..., x_n_min ),( x_0_max , x_1_max , x_2_max ,..., x_n_max )] - specificerat intervall Function Array ( Node *& Z ){ Om ([ x_0_min , x_1_min , x_2_min ,..., x_n_min ] < Z ){ Z = Z -> vänster ; // vänster underträd } annan Om ([ x_0_max , x_1_max , x_2_max ,..., x_n_max ] > Z ){ Z = Z -> höger ; // höger underträd } Annars { // se båda underträden i Array ( Z -> höger ); // kör funktionen för det högra underträdet Z = Z -> vänster ; // visa vänster underträd } } AnalysDet minsta antalet element som visas är uppenbarligen , där är trädets höjd. Det är också uppenbart att det maximala antalet element som visas är , det vill säga att visa alla element i trädet. Det återstår att beräkna det genomsnittliga antalet visade objekt .
- given räckvidd.
Den ursprungliga artikeln om kd-träd ger följande egenskap: för ett fast intervall.
Om vi går från höjden på trädet till antalet element, kommer detta att vara:
Sökandet efter det närmaste elementet är uppdelat i två deluppgifter: att bestämma det möjliga närmaste elementet och att hitta de närmaste elementen i ett givet intervall.
Givet ett träd . Vi sänker trädet till dess löv efter tillstånd och bestämmer det troligen närmaste elementet efter tillstånd . Efter det, från roten av trädet, lanseras algoritmen för att hitta det närmaste elementet i det givna området, som bestäms av radien .
Sökradien justeras när ett närmare element hittas.
Algoritm Z är trädets rot Lista - en lista över de närmast hittade elementen [ x_0 , x_1 , x_2 ..., x_n ] - koordinater för alla dimensioner av vårt element , för vilka den närmaste Len - minsta längd BARN - det maximala antalet barn för varje element Funktionen Maybe_Near ( Node *& Z ) { // sök efter det närmaste möjliga elementet medan ( Z ) { for ( i = 0 ; i < N ; i ++ ) { // kontrollera element i noden len_cur = sqrt (( x_0 - x [ i ] _0 ) ^ 2 + ( x_1 - x [ i ] _1 ) ^ 2 + . .. + ( x_n - x [ i ] _n ) ^ 2 ); // längd på nuvarande element if ( Len > längd på nuvarande element ) { Len = len_cur ; // ställ in ny längd Ta bort ( Lista ); // rensa listan Lägg till ( Lista ); // lägg till ett nytt element i listan } else if ( längder är lika ) { Lägg till ( Lista ); // lägg till ett nytt element i listan } if (( x_0 == x [ i ] _0 ) && ( x_1 == x [ i ] _1 ) && ... && ( x_n == x [ i ] _n )) { retur 1 ; } } om ([ x_0 , x_1 , x_2 ..., x_n ] < Z ) Z = Z -> vänster ; // vänster underträd om ([ x_0 , x_1 , x_2 ..., x_n ] > Z ) Z = Z -> höger ; // höger underträd } } Funktion Nära ( Node *& Z ) { // söker rekursivt efter det närmaste elementet i det givna intervallet om ( ! Z ) { returnera Lista ; } len_cur = sqrt (( x_0 - x [ i ] _0 ) ^ 2 + ( x_1 - x [ i ] _1 ) ^ 2 + ... + ( x_n - x [ i ] _n ) ^ 2 ); // avstånd från vår punkt till den nuvarande om ( len_cur < Len ) { // hittade en längd som är mindre än den minsta Len = len_cur ; // ställa in en ny minimilängd Delete ( List ); // rensa listan - trots allt är alla element som hittats hittills längre än det nuvarande Add ( List , Z ); // add the current element to the list } else if ( len_cur == Len ) { // längden är lika med minimum Add ( List , Z ); // lägg bara till ett nytt element i listan } for ( i = 0 ; i < BARN ; i ++ ) { // gör samma sak för alla barn Nära ( Z -> barn [ i ]); // visa alla underträd } } AnalysDet minsta antalet element som visas är uppenbarligen , där h är trädets höjd. Det är också uppenbart att det maximala antalet element som visas är , det vill säga att visa alla noder. Det återstår att beräkna det genomsnittliga antalet visade objekt.
är ett givet element med avseende på vilket du vill hitta det närmaste. Denna uppgift är uppdelad i två deluppgifter: att hitta det närmaste elementet i en nod och att hitta det närmaste elementet i ett givet intervall. För att lösa det första delproblemet krävs en nedstigning längs trädet, det vill säga .
För den andra deluppgiften, som vi redan har beräknat, tar sökningen efter element i ett givet intervall . För att hitta genomsnittet, lägg till dessa två värden:
.
Träd (datastruktur) | |
---|---|
Binära träd | |
Självbalanserande binära träd |
|
B-träd | |
prefix träd |
|
Binär uppdelning av utrymme | |
Icke-binära träd |
|
Bryter upp utrymmet |
|
Andra träd |
|
Algoritmer |
Data struktur | |
---|---|
Listor | |
Träd | |
Räknar | |
Övrig |