Innanzitutto, suppongo che tutti gli elementi siano distinti. Nessuna quantità di sequenzializzazioni ti dirà la forma di un albero con elementi [3,3,3,3,3]
. Naturalmente è possibile ricostruire alcuni alberi con elementi duplicati; Non so quali belle condizioni sufficienti esistano.
Continuando sui risultati negativi, non è possibile ricostruire completamente un albero binario solo dalle sue sequenzializzazioni pre-ordine e post-ordine. [1,2]
preordine, il [2,1]
post-ordine deve avere 1
il root, ma 2
può essere il bambino sinistro o il bambino giusto. Se non ti interessa questa ambiguità, puoi ricostruire l'albero con il seguente algoritmo:
- Lascia che sia l'attraversamento del pre-ordine e [ y n , ... , y 1 ] sia l'attraversamento del post-ordine. Dobbiamo avere x 1 = y 1 , e questa è la radice dell'albero.[x1,…,xn][yn,…,y1]x1=y1
- è il figlio più a sinistra della radice e y 2 è il figlio più a destra. Se x 2 = y 2 , il nodo radice è unario; ricorrere su [ x 2 , ... , x n ] e [ y n , ... , y 2 ] per costruire la singola sottostruttura.x2y2x2=y2[x2,…,xn][yn,…,y2]
- Altrimenti, sia che j siano gli indici in modo tale che x 2 = y i e y 2 = x j . [ x 2 , … , x j - 1 ] è l'attraversamento del preordine della sottostruttura sinistra, [ x j , … , x n ] quello della sottostruttura destra, e allo stesso modo per gli attraversamenti post ordine. La sottostruttura sinistra ha j - 2 = n - i +ijx2=yiy2=xj[x2,…,xj−1][xj,…,xn] elementi e la sottostruttura destra ha i - 2 = n - j + 1 elementi. Richiedere una volta per ogni sottostruttura.
A proposito, questo metodo si generalizza agli alberi con ramificazione arbitraria. Con una ramificazione arbitraria, scopri l'estensione del sottotree sinistro e taglia i suoielementi j - 2 da entrambe le liste, quindi ripeti per tagliare il secondo sottotree da sinistra, e così via.j−2=n−i+1i−2=n−j+1
j−2
O(n2)Θ(n2)O(nlg(n))nlg(n)
[x1,…,xn][z1,…,zn]
- x1
- kzk=x1[z1,…,zk−1][zk+1,…,zn][x2,…,xk][xk+1,…,xn]
O(n2)O(nlg(n))
L'ordine postale più l'ordine è ovviamente simmetrico.