從其連結串列表示構建完全二叉樹


在這個問題中,我們將把連結串列轉換為完全二叉樹。

我們可以將連結串列視為陣列。連結串列的第 p 個元素是二叉樹的第 2*p + 1 和 2*p + 2 個元素的父節點。因此,我們可以遍歷連結串列的每個元素並構建二叉樹。

問題陳述 - 我們給定一個包含 N 個節點的連結串列。我們需要從給定的連結串列構建完全二叉樹。還要列印二叉樹的中序遍歷。

注意 - 在完全二叉樹中,除了樹的最後一層外,樹的所有層都已完全填充。

示例

輸入

L_head = 48 -> 142 -> 18 -> 72 -> 10 -> 12 -> 94 -> 45

輸出

45, 72, 142, 10, 48, 12, 18, 94
                 
                      48
	             /  \
                   142  18
	          /  \  /  \
                 72  10 12 94
                /
               45

說明 - 中序遍歷首先列印左子樹,然後列印根節點,最後列印右子樹。

輸入

L_head = 2 -> 8 -> 4 -> 5

輸出

5, 8, 2, 4
            
             2
           /   \
          8     4
         /
        5

說明 - 我們列印了給定二叉樹的中序遍歷。

輸入

L_head = NULL

輸出

NULL

說明 - 二叉樹為空,因為連結串列不包含任何節點。

方法

在連結串列中,第 P 個節點是二叉樹中 (2*p + 1) 和 (2*p + 2) 節點的父節點。

我們將使用佇列資料結構來跟蹤二叉樹的節點。使用連結串列元素建立二叉樹的節點後,我們將樹節點推入佇列。此外,在每次迭代中,我們從佇列中彈出節點,從連結串列中獲取接下來的 2 個節點,併為當前節點建立左子節點和右子節點,並將它們與父節點連線。

演算法

步驟 1 - 為連結串列建立一個 L_Node 結構,其中包含 'val' 整數變數和 'next' 指標。

步驟 2 - 為二叉樹建立一個 'B_Node' 結構,其中包含 'val' 整數和 'left' 和 'child' 指標。

步驟 3 - 接下來,定義 insertInList() 函式來建立連結串列。

步驟 3.1 - 在 insertInList() 函式中,定義一個新的 L_Node。

步驟 3.2 - 初始化新節點的值。此外,將新節點的 'next' 指標初始化為頭節點,以便將新節點插入到連結串列的開頭。

步驟 3.3 - 使用新節點更新頭節點。

步驟 4 - 定義 createNewNode() 函式來為二叉樹建立一個新節點。

步驟 5 - 定義 listTOBinary() 函式將連結串列轉換為二叉樹。

步驟 6 - 如果 L_head 為 NULL,則將 B_head 更新為 NULL,並執行 return 語句。

步驟 7 - 使用連結串列的 L_Node 的值建立一個新的二叉樹節點,並將其儲存在 B_head 中。此外,將 B_head 插入佇列並將 L_head 指向下一個節點。

步驟 8 - 遍歷連結串列。

步驟 8.1 - 從佇列中彈出第一個節點並將其儲存在 'parent' 節點中。此外,建立 'l_child' 和 'r_child' 指標並初始化為 NULL。

步驟 8.2 - 為二叉樹建立一個新節點,使用 L_head 節點的值初始化,並將其儲存到 l_child 節點中。

步驟 8.3 - 將 l_child 節點插入佇列,並將 L_head 移動到下一個節點。

步驟 8.4 - 如果 l_head 不為空,則建立一個新節點,並將其分配給 r_child 節點。此外,將 r_child 節點插入佇列並將 L_head 移動到下一個節點。

步驟 9 - 使用 l_child 和 r_child 節點更新父節點的左指標和右指標。

步驟 10 - 建立 inorder() 函式以顯示新建立樹的中序遍歷。

示例

#include <iostream>
#include <string>
#include <queue>
using namespace std;

// Structure for tree and linked list
struct L_Node {
    int val;
    L_Node *next;
};
struct B_Node {
    int val;
    B_Node *left, *right;
};
// To insert a node in a linked list
void InsertInList(struct L_Node **head, int new_val) {
    struct L_Node *temp_node = new L_Node;
    temp_node->val = new_val;
    // Insert node at start
    temp_node->next = (*head);
    // Change head node pointer
    (*head) = temp_node;
}
// For Creating a new node for the tree
B_Node *createNewNode(int val) {
    B_Node *temp_node = new B_Node;
    temp_node->val = val;
    temp_node->left = temp_node->right = NULL;
    return temp_node;
}
void listTOBinary(L_Node *L_head, B_Node *&B_head) {
    queue<B_Node *> que;
    // For empty linked list
    if (L_head == NULL) {
        B_head = NULL;
        return;
    }
    // Initialize the head node of the binary tree
    B_head = createNewNode(L_head->val);
    que.push(B_head);
    // Move list pointer
    L_head = L_head->next;
    // Traverse until we reach at the end of the list
    while (L_head) {
        // Take node from queue
        B_Node *parent = que.front();
        que.pop();
        // Add the next two nodes as a child of the parent node
        B_Node *l_child = NULL, *r_child = NULL;
        l_child = createNewNode(L_head->val);
        que.push(l_child);
        L_head = L_head->next;
        if (L_head) {
            r_child = createNewNode(L_head->val);
            que.push(r_child);
            L_head = L_head->next;
        }
        parent->left = l_child;
        parent->right = r_child;
    }
}
void inorder(B_Node *B_head) {
    if (B_head) {
        inorder(B_head->left);
        cout << B_head->val << " ";
        inorder(B_head->right);
    }
}
int main() {
    struct L_Node *L_head = NULL;
    InsertInList(&L_head, 45);
    InsertInList(&L_head, 94);
    InsertInList(&L_head, 12);
    InsertInList(&L_head, 10);
    InsertInList(&L_head, 72);
    InsertInList(&L_head, 18);
    InsertInList(&L_head, 142);
    InsertInList(&L_head, 48);
    B_Node *B_head;
    listTOBinary(L_head, B_head);
    cout << "The Inorder Traversal of the newly created Binary Tree is: \n";
    inorder(B_head);
    return 0;
}

輸出

The Inorder Traversal of the newly created Binary Tree is: 
45 72 142 10 48 12 18 94

時間複雜度 - O(N),其中 N 是連結串列中的節點數。

空間複雜度 - O(N) 以建立新的二叉樹。

在這裡,我們遍歷了連結串列併為每個連結串列節點建立了一個新的二叉樹節點。之後,我們將當前節點附加到其父節點。程式設計師可以嘗試將陣列轉換為二叉樹以進行更多練習。

更新於: 2023年8月2日

490 次瀏覽

開啟你的 職業生涯

透過完成課程獲得認證

開始
廣告