ในปัญหานี้ เราได้รับอาร์เรย์ preOrder[] ที่แสดงถึงการข้ามผ่านของการสั่งซื้อล่วงหน้าของทรีการค้นหาแบบไบนารี งานของเราคือค้นหาการข้ามผ่านรายการสั่งซื้อหลังการสั่งซื้อของ BST จากการส่งผ่านการสั่งซื้อล่วงหน้า
มาดูตัวอย่างเพื่อทำความเข้าใจปัญหากัน
อินพุต
preOrder[] = {5, 2, 4, 7, 12} ผลลัพธ์
{4, 2, 12, 7, 5} แนวทางการแก้ปัญหา
วิธีแก้ปัญหาอย่างง่ายคือการสร้าง BST จากการข้ามผ่านของการสั่งซื้อล่วงหน้าที่กำหนด แล้วทำการขวางทาง postorder ของต้นไม้ วิธีแก้ปัญหานี้ใช้ได้ แต่วิธีแก้ปัญหาที่มีประสิทธิภาพมากกว่าคือ
เราจะสำรวจอาร์เรย์ที่สั่งซื้อล่วงหน้าโดยจำกัดค่าเพื่อแยกค่าของทรีย่อยด้านซ้ายและขวา
ลำดับการข้ามผ่านคือ −
preOrder : Root -> Left -> Right postOrder : Left -> Right -> Root
สำหรับองค์ประกอบแรกในการสั่งซื้อล่วงหน้าซึ่งเป็นองค์ประกอบรูท สำหรับสิ่งนี้ ขีดจำกัดคือ {INT_MIN, Root} จากนั้นสำรวจอาร์เรย์ที่สั่งซื้อล่วงหน้าและองค์ประกอบแรก และสลับองค์ประกอบทั้งหมดที่จำกัดด้วยค่าสุดท้ายของขีดจำกัด ในทำนองเดียวกัน เราจะทำสิ่งนี้สำหรับทรีย่อยด้านขวาและเพิ่มรูทในตอนท้าย
โปรแกรมเพื่อแสดงการทำงานของโซลูชันของเรา
ตัวอย่าง
#include <iostream>
using namespace std;
void findPostOrderTraversalRec(int pre[], int n, int lowerLimit, int
upperLimit, int& index){
if (index == n)
return;
if (pre[index] < lowerLimit || pre[index] > upperLimit)
return;
int currNode = pre[index];
index++;
findPostOrderTraversalRec(pre, n, lowerLimit, currNode, index);
findPostOrderTraversalRec(pre, n, currNode, upperLimit, index);
cout<<currNode<<" ";
}
void findPostOrderTraversalFromPreOrder(int pre[], int n){
int index = 0;
findPostOrderTraversalRec(pre, n, -1000, 1000, index);
}
int main(){
int pre[] = { 5, 2, 4, 7, 12 };
int n = sizeof(pre) / sizeof(pre[0]);
cout<<"PreOrder Traversal : \t";
for(int i = 0; i < n ; i++)
cout<<pre[i]<<" ";
cout<<endl<<"Post Order Traversal : \t";
findPostOrderTraversalFromPreOrder(pre, n);
return 0;
} ผลลัพธ์
PreOrder Traversal − 5 2 4 7 12 Post Order Traversal − 4 2 12 7 5
อีกวิธีหนึ่งในการแก้ปัญหาคือการใช้การวนซ้ำ อย่างที่เราทราบกันดีว่าการสั่งซื้อล่วงหน้าใน root -> left -> right และ postOrder is left -> right -> root สามารถคำนวณได้โดยใช้การวนซ้ำและคำนวณองค์ประกอบเดือยซึ่งเป็นองค์ประกอบสุดท้ายขององค์ประกอบด้านซ้าย เมื่อใช้สิ่งนี้ เราจะพิมพ์ทางซ้ายก่อน จากนั้นไปทางขวา จากนั้นจึงทำการรูท
พบเดือยโดยการค้นหาดัชนีขององค์ประกอบที่ใหญ่กว่าซึ่งมีขนาดเล็กกว่ารูท
โปรแกรมเพื่อแสดงการทำงานของโซลูชันของเรา
ตัวอย่าง
#include <iostream>
using namespace std;
void findPostOrderTraversalFromPreOrder(int pre[], int n){
int pivot = 0;
for(int i = 1; i < n; i++){
if (pre[0] <= pre[i]) {
pivot = i;
break;
}
}
for(int i = pivot - 1; i > 0; i--){
cout << pre[i] << " ";
}
for(int i = n - 1; i >= pivot; i--) {
cout << pre[i] << " ";
}
cout << pre[0];
}
int main(){
int pre[] = { 5, 2, 4, 7, 12 };
int n = sizeof(pre) / sizeof(pre[0]);
cout<<"PreOrder Traversal : \t";
for(int i = 0; i < n ; i++)
cout<<pre[i]<<" ";
cout<<endl<<"Post Order Traversal : \t";
findPostOrderTraversalFromPreOrder(pre, n);
return 0;
} ผลลัพธ์
PreOrder Traversal − 5 2 4 7 12 Post Order Traversal − 4 2 12 7 5