ในปัญหานี้ เราได้รับอาร์เรย์ 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