İkili arama ağacı ön sipariş geçişi ise 6, 2, 1, 4, 3, 7, 10, 9, 11, nasıl sonrası düzen geçişini alınır?
sonrası geçişine karşı ön sipariş verin
Ön sipariş akım düğümün, ardından sol alt ağaç, sonra sağ alt ağaç sırasına göre bir ikili ağacın değerlerini çıkışı =.
Post-düzen sol alt ağaç, sonra sağ alt ağacı, geçerli düğüm sırasına göre bir ikili ağacın değerlerini çıkışı =.
İkili olarak arama ağacının sol alt kollarındaki bütün düğümlerin değerleri geçerli düğümün değerden az; ve sağ alt ağaç için aynısınız. Eğer (kök düğümün değerine yani) bir ikili arama ağacının ön sipariş dökümü başlangıcını biliyorum Dolayısıyla eğer, kolayca, kök düğüm değeri içine bütün dökümü ayrıştırmak sol alt ağaç en düğümlerin değerleri ve değerleri sağ alt ağaç nodülleri.
çıkış sonrası sırayla ağaç, tekrarlama ve çıkış yeniden sıralama uygulanır. Bu görev okuyucu üzerine bırakılır.
Sen yaparak inşa edilmiştir ağacın ön sipariş geçişi verilmiştir: çıktı, çapraz sol, sağ çapraz.
Post-düzen geçişi bir BST geliyor gibi, içinde sipariş geçişi çıkarabiliriz numaraları sıralayarak sonrası geçişine dan (çapraz sağ, çıkış Sol çapraz). Örnekte, içinde sipariş geçişi, 1, 2, 3, 4, 6, 7, 9, 10, 11'dir.
İki geçişleri itibaren sonra orijinal ağacı oluşturabilirsiniz. Şimdi bunun için daha basit bir örnek verelim:
- Ön Sipariş: 2, 1, 4, 3
- In-sırayla: 1, 2, 3, 4
ön sipariş geçişi 4 sağ alt ağacın düşer, bize 2. İn-sipariş geçişi bize 1 sol alt ağaca düşmeleri ve 3 anlatır olarak ağacın kökünü verir. tek öğesi içeren olarak sol alt ağacın yapısı önemsiz olduğunu. Biz 4 sağ alt ağacın kökü olduğunu ve bu Dan 4, 3.: sağ alt ağacın ön sipariş geçişi orijinal ön sipariş kastetmek gelen bu alt ağacındaki elementlerin sipariş alarak hacmileriyle içinde sipariş kastetmek itibaren (3, 4) biz 3 sol alt ağaca düştüğünü biliyoruz. Bizim nihai ağaç gibi görünür:
2
/ \
1 4
/
3
ağaç yapısında ile, ağaç yürüyerek sonrası düzen geçişi alabilirsiniz: Sol çapraz, sağa çıkış çapraz. Bu örnek için, sonrası geçişine 1, 3, 4, 2 'dir.
algoritmayı genelleme için:
- ön sipariş kastetmek ilk öğesi ağacının köküdür. root az Elemanları sol alt ağaç oluşturmaktadır. root daha büyük Elemanları sağ alt ağaç oluşturmaktadır.
- biz onlar orijinal ön sipariş kastetmek görünen sırayla yerleştirilen alt ağaçta olduğu ortaya çalışmış elemanlardan oluşur ön sipariş kastetmek ile adım 1 kullanılarak sol ve sağ alt ağaçların yapısını bulun.
- Verilen ön sipariş kastetmek ile ilişkili sonrası düzen geçişini almak sonrası sırası ile sonuçlanır ağacı Traverse.
Yukarıdaki algoritma kullanarak, söz konusu ön sipariş geçişi ile bağlantılı sonrası geçişine: 1, 3, 4, 2, 9, 11, 10, 7, 6, bir egzersiz orada bırakılır alınıyor.
Ondrej Tucny cevabı dayanarak. BST sadece için geçerli
örnek:
20
/ \
10 30
/\ \
6 15 35
Ön Sipariş = 20 10 6 15 30 35
Sonra = 6 15 10 35 30 20
Ön Sipariş geçişi, bir TSİ için; dizinin ilk elemanı Bu bizim ağacın köküdür 20'dir. 20 daha az olan bir dizi tüm sayılar da sol alt ağacı oluşturmak ve daha fazla sayıda sağ alt ağacını oluşturur.
//N = number of nodes in BST (size of traversal array)
int post[N] = {0};
int i =0;
void PretoPost(int pre[],int l,int r){
if(l==r){post[i++] = pre[l]; return;}
//pre[l] is root
//Divide array in lesser numbers and greater numbers and then call this function on them recursively
for(int j=l+1;j<=r;j++)
if(pre[j]>pre[l])
break;
PretoPost(a,l+1,j-1); // add left node
PretoPost(a,j,r); //add right node
//root should go in the end
post[i++] = pre[l];
return;
}
Herhangi bir hata varsa lütfen beni düzeltin.
Eğer ön sipariş geçişi sonuçları verilmiştir. Daha sonra uygun bir ikili arama ağacına değerlerini koymak ve sadece elde BST için post-düzen geçişi algoritması izleyin.
Bu eski olduğunu biliyorum ama daha iyi bir çözüm yoktur.
Biz ön siparişten sonrası sipariş almak için bir BST yeniden inşa etmek gerekmez.
İşte yinelemeli yapar basit bir piton kodudur:
import itertools
def postorder(preorder):
if not preorder:
return []
else:
root = preorder[0]
left = list(itertools.takewhile(lambda x: x < root, preorder[1:]))
right = preorder[len(left) + 1:]
return postorder(left) + postorder(right) + [root]
if __name__ == '__main__':
preorder = [20, 10, 6, 15, 30, 35]
print(postorder(preorder))
Çıktı:
[6, 15, 10, 35, 30, 20]
Açıklama :
Biz ön sipariş olduğunu biliyorum. Bu kök dizinde olduğu anlamına gelir 0BST değerlerin listenin. Ve biz kök aşağıdaki unsurları olduğunu biliyoruz:
- İlk: daha az elemanları
rootkök sol alt ağacı, ait olan - İkinci: daha büyük elemanları
rootkök sağ alt ağacı, ait olan
Sonra sadece yinelemeli (hala ön sıradadır) hem alt ağaçlar üzerindeki fonksiyonunu ve ardından zincirini çağrı left + right + root(post-order olan).
Eğer ön sipariş vermek verildi ve postorder dönüştürmek istiyorsanız. Sonra hep artan sayıları vermek amacıyla bir BST olduğunu unutmamak gerek order.Thus bir ağacı oluşturmak için ön siparişe yanı sıra hem Inorder var.
ön sipariş: 6, 2, 1, 4, 3, 7, 10, 9, 11
sırayla: 1, 2, 3, 4, 6, 7, 9, 10, 11
Ve onun postorder: 1 3 4 2 9 11 10 7 6
İşte ikili arama ağacının ön sipariş geçişi dizisi verilmiştir. Yani BST.We ait kök edecek ön sipariş dizinin 1 eleman ön sipariş dizideki eleman kök düğümü kalacak daha azdır BST ve BST.All sağ kısmının sol kısmını bulup öncesi tüm eleman olacak kök doğru düğüm olacaktır sonra mertebeden dizi daha fazladır.
#include <bits/stdc++.h>
using namespace std;
int arr[1002];
int no_ans = 0;
int n = 1000;
int ans[1002] ;
int k = 0;
int find_ind(int l,int r,int x){
int index = -1;
for(int i = l;i<=r;i++){
if(x<arr[i]){
index = i;
break;
}
}
if(index == -1)return index;
for(int i =l+1;i<index;i++){
if(arr[i] > x){
no_ans = 1;
return index;
}
}
for(int i = index;i<=r;i++){
if(arr[i]<x){
no_ans = 1;
return index;
}
}
return index;
}
void postorder(int l ,int r){
if(l < 0 || r >= n || l >r ) return;
ans[k++] = arr[l];
if(l==r) return;
int index = find_ind(l+1,r,arr[l]);
if(no_ans){
return;
}
if(index!=-1){
postorder(index,r);
postorder(l+1,index-1);
}
else{
postorder(l+1,r);
}
}
int main(void){
int t;
scanf("%d",&t);
while(t--){
no_ans = 0;
int n ;
scanf("%d",&n);
for(int i = 0;i<n;i++){
cin>>arr[i];
}
postorder(0,n-1);
if(no_ans){
cout<<"NO"<<endl;
}
else{
for(int i =n-1;i>=0;i--){
cout<<ans[i]<<" ";
}
cout<<endl;
}
}
return 0;
}
Biz Preorder ebeveyn, sol, sağ dizi izleyin Bildiğimiz.
ağaç oluşturmak için biz kaç temel adımları-izlemeniz gerekir:
Sorunuzun serisinin 6. oluşur 2,1,4,3,7,10,9,11
Puan-:
- Serinin ilk sayı kökü olacaktır (ana) yani 6
2.Find bu serinin 7 den büyük 6 böyledir sayı çok doğru düğüm (7) sol alt ağaçlar burada başlayarak bu numaraya bırakılacaktır bu serideki ilk büyük sayıdır.
6
/ \
2 7
/ \ \
1 4 10
/ / \
3 9 11
3.same yolu sağa, BST sol yani, kök temel kural
sonrası için bir dizi 1,3,4,2,9,11,10,7,6 L, R, N, yani olacak
Bu Python geçişi postorder için ön sipariş ait kodudur. Eğer kastetmek her türlü bulabilirsiniz yüzden bir ağaç oluşturulmadan am
def postorder(root):
if root==None:
return
postorder(root.left)
print(root.data,end=" ")
postorder(root.right)
def preordertoposorder(a,n):
root=Node(a[0])
top=Node(0)
temp=Node(0)
temp=None
stack=[]
stack.append(root)
for i in range(1,len(a)):
while len(stack)!=0 and a[i]>stack[-1].data:
temp=stack.pop()
if temp!=None:
temp.right=Node(a[i])
stack.append(temp.right)
else:
stack[-1].left=Node(a[i])
stack.append(stack[-1].left)
return root
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
a=[40,30,35,80,100]
n=5
root=preordertoposorder(a,n)
postorder(root)
# print(root.data)
# print(root.left.data)
# print(root.right.data)
# print(root.left.right.data)
# print(root.right.right.data)
İşte) tam koddur
class Tree:
def __init__(self, data = None):
self.left = None
self.right = None
self.data = data
def add(self, data):
if self.data is None:
self.data = data
else:
if data < self.data:
if self.left is None:
self.left = Tree(data)
else:
self.left.add(data)
elif data > self.data:
if self.right is None:
self.right = Tree(data)
else:
self.right.add(data)
def inOrder(self):
if self.data:
if self.left is not None:
self.left.inOrder()
print(self.data)
if self.right is not None:
self.right.inOrder()
def postOrder(self):
if self.data:
if self.left is not None:
self.left.postOrder()
if self.right is not None:
self.right.postOrder()
print(self.data)
def preOrder(self):
if self.data:
print(self.data)
if self.left is not None:
self.left.preOrder()
if self.right is not None:
self.right.preOrder()
arr = [6, 2, 1, 4, 3, 7, 10, 9, 11]
root = Tree()
for i in range(len(arr)):
root.add(arr[i])
print(root.inOrder())
, Bir ikili arama ağacı olduğundan, inorder geçişi her zaman sıralı unsurlar olacaktır. (Sol <kök <sağda)
böylece, kolayca hangi ilk olarak in-düzen geçişi sonuçları yazabilirsiniz: 1,2,3,4,6,7,9,10,11
6, 2, 1, 4, 3, 7, 10, 9, 11: Ön sipariş verilen
In-düzen: sol, kök, sağ ön sipariş: root, sol, sağ Sonrası sırası: sol, sağ, kök
Şimdi, biz ön sipariş aldığı, kök 6'dır.
Şimdi, içinde sipariş ve ön sipariş sonuçları kullanılarak: Adım 1:
6
/ \
/ \
/ \
/ \
{1,2,3,4} {7,9,10,11}
2. Adım: Bir sonraki kök içinde sipariş geçişi, 2 kullanılarak şöyledir:
6
/ \
/ \
/ \
/ \
2 {7,9,10,11}
/ \
/ \
/ \
1 {3,4}
Adım 3: Benzer şekilde, bir sonraki kök 4'tür:
6
/ \
/ \
/ \
/ \
2 {7,9,10,11}
/ \
/ \
/ \
1 4
/
3
Adım 4: Bir sonraki kök 3'tür, ancak başka unsur "3" için çocuk ağacında uygun olması kaldığını. Şimdi 7 olarak sonraki kökünü göz önüne alındığında,
6
/ \
/ \
/ \
/ \
2 7
/ \ \
/ \ {9,10,11}
/ \
1 4
/
3
Adım 5: Sonraki kök 10:
6
/ \
/ \
/ \
/ \
2 7
/ \ \
/ \ 10
/ \ / \
1 4 9 11
/
3
1, 3, 4, 2, 9, 11, 10, 7, 6: Bu, bir ağaç oluşturmak ve son olarak onun sonrası geçişine bulabilirsiniz nasıl,













