Xây dựng cây nhị phân từ dãy trung thứ tự và hậu thứ tự

Bài toán

Cho hai mảng số nguyên trungTuhauTu tương ứng biểu diễn dãy trung thứ tự và hậu thứ tự của cùng một cây nhị phân. Nhiệm vụ là xây dựng lại cây nhị phân từ hai dãy này.

Ví dụ 1:

<strong>Đầu vào:</strong> trungTu = [9,3,15,20,7], hauTu = [9,15,7,20,3]<br><strong>Đầu ra:</strong> [3,9,20,null,null,15,7]

Ví dụ 2:

<strong>Đầu vào:</strong> trungTu = [-1], hauTu = [-1]<br><strong>Đầu ra:</strong> [-1]

Phương pháp giải

Bước 1: Gốc cây luôn là phần tử cuối cùng trong dãy hậu thứ tự.
Bước 2: Sử dụng bảng tra cứu nhanh để xác định vị trí của gốc trong dãy trung thứ tự, từ đó phân chia dãy thành nhánh trái và phải.
Bước 3: Áp dụng đệ quy để xây dựng các cây con trái/phải dựa trên kích thước được xác định.

Mã nguồn C++

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

struct Node {
    int giaTri;
    Node* conTrai;
    Node* conPhai;
    Node(int x) : giaTri(x), conTrai(nullptr), conPhai(nullptr) {}
};

class GiaiPhap {
public:
    Node* taoCay(vector<int>& trungTu, vector<int>& hauTu) {
        if (trungTu.empty()) return nullptr;
        
        unordered_map<int, int> bangTra;
        for (int i = 0; i < trungTu.size(); ++i)
            bangTra[trungTu[i]] = i;
            
        return xayDung(trungTu, 0, trungTu.size()-1, 
                       hauTu, 0, hauTu.size()-1, bangTra);
    }
    
private:
    Node* xayDung(vector<int>& trungTu, int trungBatDau, int trungKetThuc,
                 vector<int>& hauTu, int hauBatDau, int hauKetThuc,
                 unordered_map<int, int>& bangTra) {
        if (trungBatDau > trungKetThuc || hauBatDau > hauKetThuc)
            return nullptr;
            
        int giaTriGoc = hauTu[hauKetThuc];
        Node* nutGoc = new Node(giaTriGoc);
        int viTriGoc = bangTra[giaTriGoc];
        
        int doDaiTrai = viTriGoc - trungBatDau;
        int doDaiPhai = trungKetThuc - viTriGoc;
        
        nutGoc->conTrai = xayDung(trungTu, trungBatDau, viTriGoc-1,
                                 hauTu, hauBatDau, hauBatDau+doDaiTrai-1, bangTra);
                                 
        nutGoc->conPhai = xayDung(trungTu, viTriGoc+1, trungKetThuc,
                                hauTu, hauBatDau+doDaiTrai, hauKetThuc-1, bangTra);
                                
        return nutGoc;
    }
};

Thẻ: cây nhị phân đệ quy duyệt cây

Đăng vào ngày 3 tháng 7 lúc 10:33