91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何根據前序遍歷和中序遍歷創建python二叉樹

發布時間:2021-12-13 17:17:42 來源:億速云 閱讀:306 作者:柒染 欄目:大數據

今天就跟大家聊聊有關如何根據前序遍歷和中序遍歷創建python二叉樹,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

Contents

前言四種遍歷樹的方法簡介簡介兩種快速獲得遍歷結果的方法根據前序遍歷和后續遍歷創建樹代碼實現四種遍歷樹的方法的代碼

不說廢話了,下面講講如何根據pre_order和in_order創建二叉樹。

 

四種遍歷樹的方法簡介

 
簡介

首先這里簡單介紹一下二叉樹的4種遍歷方式:

  • 前序遍歷(pre_order)

  • 中序遍歷(in_order)

  • 后序遍歷(post_order)

  • 層序遍歷(level_order)

至于這些遍歷的代碼放在文章的最后。

前序遍歷就是先對當前的根節點進行操作,然后到左子節點,再到右子節點!

中序遍歷就是先對當前左子節點進行操作,然后到當前根節點,再到右子節點!

后序遍歷就是先對當前左子節點進行操作,然后到右子節點,再到當前根節點!

層序遍歷就是按照從上到下從左到右的順序對每個節點進行操作!代碼寫起來比前三個復雜點,得借助隊列,并用迭代的方式來做。

如下圖(之前上課做的筆記):

如何根據前序遍歷和中序遍歷創建python二叉樹

 
兩種快速獲得遍歷結果的方法

另外,介紹兩個 可以快速地 根據樹的形狀 得出 前序、后序、中序 的遍歷結果。

法一:

如何根據前序遍歷和中序遍歷創建python二叉樹

法二:

如何根據前序遍歷和中序遍歷創建python二叉樹

 

根據前序遍歷和后續遍歷創建樹

給你一個數組,用這個數組的值來創建一個樹,結果有多種可能:

如何根據前序遍歷和中序遍歷創建python二叉樹

其中n是數組中元素的個數!

但是,如果我們給了兩個數組,分別是前序遍歷和后續遍歷的結果,那么我們就能創建唯一的一個樹!

Note:要求數組中的元素不重復,是唯一的!

看過上面對樹的那幾種遍歷方式后,可以發現:

Note:下面的這個過程有點枯燥,我表述地也不太好,可以看后面的圖。

  • 前序遍歷的第一個元素就是樹的根節點;第二個元素是根節點的左子節點,這個左子節點也是后面的根節點;

  • 根節點把中序遍歷的數組一分為二,中序遍歷的數組中:根節點的左邊是左樹,根節點的右邊是右樹

  • 如何根據前序遍歷和中序遍歷創建python二叉樹

  • 所以,我們就對前序遍歷的數組進行遍歷,當前索引記為pre_i,在每次遍歷中,到中序遍歷的數組中找這個pre_i對應的值,用這個pre_i把中序遍歷的結果一分為二。這樣往復下去就能還原樹了。

下面我畫一下整個流程:

如何根據前序遍歷和中序遍歷創建python二叉樹

大概就是這樣,不斷地對中序遍歷的數組一分為二(根據前序遍歷的數組的當前元素進行分割);中序遍歷的數組的當前元素就是當前的根節點。

 
代碼實現

先定義樹的節點:

template <class T>
struct Node{
    T val;
    Node* left;
    Node* right;

    explicit Node(T v) : val(v), left(nullptr), right(nullptr){}
};
 

根據前序遍歷和中序遍歷創建樹:

/**
 * @brief 根據前序遍歷和中序遍歷創建樹
 * @param[in] pre_vec   前序遍歷的數組
 * @param[in] in_vec    中序遍歷的數組
 * @param[in] left_in   中序遍歷當前段的左邊界
 * @param[in] right_in  中序遍歷當前段的右邊界(超尾)
 * @static pre_i        前序遍歷的當前的索引
 *
 * @note 在每一層遞歸中,當前的 中序遍歷 數組段 被分為:[left_in, pre_i), pre_i, [pre_i+1, right_in)
 * */
template <class T>
Node<T>* CreateTreeR(vector<T>& pre_vec, vector<T>& in_vec, int left_in, int right_in)
{
    static int pre_i = 0;

    if (left_in < right_in)
    {
        /// 從 前序遍歷 的數組中 獲取 當前 根節點!
        T cur_root_val = pre_vec.at(pre_i);
        auto* cur_root = new Node<T>(cur_root_val);

        /// 遍歷 中序遍歷 的數組,找到當前根節點對應的索引
        int i = left_in;
        while (i < right_in && cur_root_val != in_vec.at(i)) ++i;

        /// 下次遞歸前 pre_i 是需要向后移動一位的
        ++pre_i;

        /// 一分為二!(注意,i是當前節點的索引哦!)
        cur_root->left  = CreateTreeR(pre_vec, in_vec, left_in, i);              /// 左樹
        cur_root->right = CreateTreeR(pre_vec, in_vec, i+1, right_in);   /// 右樹

        return cur_root;
    }

    /// 當分到只剩最后一個元素時就返回空了
    return nullptr;
}
 

測試這段程序

對創建出來的這個樹,用四種遍歷方法分別遍歷一下子,四種遍歷的代碼在文末。

如何根據前序遍歷和中序遍歷創建python二叉樹


 

如何根據前序遍歷和中序遍歷創建python二叉樹


上面這個是數字的,我現在拿字符串的試試:

如何根據前序遍歷和中序遍歷創建python二叉樹


 

如何根據前序遍歷和中序遍歷創建python二叉樹


 

四種遍歷樹的方法的代碼

1.層序遍歷

/**
 * @brief 樹的層序遍歷
 * */
 template<class T>
 void LevelOrder(Node<T>* root, vector<T>& vec)
{
     /// 如果根節點為空就直接返回
     if (!root) return;

     /// 定義一個隊列放所有可能會成為 "根節點" 的節點(每次循環中都會pop出一個 "根節點" )
     queue< Node<T>* > q;
     q.push(root);

     while (!q.empty())
     {
         /// 從隊列中拿出最前面的根節點
         Node<T>* cur_root = q.front();  /// 這個變量在while外面聲明更好,不用每次都創建一個新變量。
         q.pop();
         /// 保存當前 "根節點" 的值
         vec.push_back(cur_root->val);

         /// 如果左子節點非空就把左子節點放入隊列
         if (cur_root->left)
             q.push(cur_root->left);

         /// 如果右子節點非空就把右子節點放入隊列
         if (cur_root->right)
             q.push(cur_root->right);
     }
}
 

2.前序遍歷

/**
 * @brief 樹的前序遍歷
 * */
template<class T>
void PreOrder(Node<T>* root, vector<T>& vec)
{
    if (root)
    {
        vec.push_back(root->val);
        PreOrder(root->left, vec);
        PreOrder(root->right, vec);
    }
}
 

3.中序遍歷

/**
 * @brief 樹的中序遍歷
 * */
template<class T>
void InOrder(Node<T>* root, vector<T>& vec)
{
    if (root)
    {
        InOrder(root->left, vec);
        vec.push_back(root->val);
        InOrder(root->right, vec);
    }
}
 

4.后序遍歷

/**
 * @brief 樹的后序遍歷
 * */
template<class T>
void PostOrder(Node<T>* root, vector<T>& vec)
{
    if (root)
    {
        PostOrder(root->left, vec);
        PostOrder(root->right, vec);
        vec.push_back(root->val);
    }
}

看完上述內容,你們對如何根據前序遍歷和中序遍歷創建python二叉樹有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盘锦市| 邯郸市| 马边| 方城县| 云浮市| 南安市| 北碚区| 临海市| 阿图什市| 措勤县| 利津县| 神池县| 米易县| 汤原县| 广安市| 文安县| 瑞金市| 卓尼县| 调兵山市| 舞阳县| 十堰市| 尉犁县| 辛集市| 寿阳县| 城步| 南和县| 江孜县| 巴马| 武功县| 墨竹工卡县| 合山市| 石首市| 山阴县| 稻城县| 盱眙县| 潞西市| 仙桃市| 共和县| 和龙市| 宁强县| 巍山|