欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

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

成都創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目做網(wǎng)站、網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元柞水做網(wǎng)站,已為上家服務(wù),為柞水各地企業(yè)和個人服務(wù),聯(lián)系電話:028-86922220

Contents

前言四種遍歷樹的方法簡介簡介兩種快速獲得遍歷結(jié)果的方法根據(jù)前序遍歷和后續(xù)遍歷創(chuàng)建樹代碼實現(xiàn)四種遍歷樹的方法的代碼

不說廢話了,下面講講如何根據(jù)pre_order和in_order創(chuàng)建二叉樹。

 

四種遍歷樹的方法簡介

 
簡介

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

  • 前序遍歷(pre_order)

  • 中序遍歷(in_order)

  • 后序遍歷(post_order)

  • 層序遍歷(level_order)

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

前序遍歷就是先對當(dāng)前的根節(jié)點進行操作,然后到左子節(jié)點,再到右子節(jié)點!

中序遍歷就是先對當(dāng)前左子節(jié)點進行操作,然后到當(dāng)前根節(jié)點,再到右子節(jié)點!

后序遍歷就是先對當(dāng)前左子節(jié)點進行操作,然后到右子節(jié)點,再到當(dāng)前根節(jié)點!

層序遍歷就是按照從上到下從左到右的順序?qū)γ總€節(jié)點進行操作!代碼寫起來比前三個復(fù)雜點,得借助隊列,并用迭代的方式來做。

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

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

 
兩種快速獲得遍歷結(jié)果的方法

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

法一:

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

法二:

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

 

根據(jù)前序遍歷和后續(xù)遍歷創(chuàng)建樹

給你一個數(shù)組,用這個數(shù)組的值來創(chuàng)建一個樹,結(jié)果有多種可能:

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

其中n是數(shù)組中元素的個數(shù)!

但是,如果我們給了兩個數(shù)組,分別是前序遍歷和后續(xù)遍歷的結(jié)果,那么我們就能創(chuàng)建唯一的一個樹!

Note:要求數(shù)組中的元素不重復(fù),是唯一的!

看過上面對樹的那幾種遍歷方式后,可以發(fā)現(xiàn):

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

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

  • 根節(jié)點把中序遍歷的數(shù)組一分為二,中序遍歷的數(shù)組中:根節(jié)點的左邊是左樹,根節(jié)點的右邊是右樹

  • 如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

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

下面我畫一下整個流程:

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹

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

 
代碼實現(xiàn)

先定義樹的節(jié)點:

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

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

根據(jù)前序遍歷和中序遍歷創(chuàng)建樹:

/**
 * @brief 根據(jù)前序遍歷和中序遍歷創(chuàng)建樹
 * @param[in] pre_vec   前序遍歷的數(shù)組
 * @param[in] in_vec    中序遍歷的數(shù)組
 * @param[in] left_in   中序遍歷當(dāng)前段的左邊界
 * @param[in] right_in  中序遍歷當(dāng)前段的右邊界(超尾)
 * @static pre_i        前序遍歷的當(dāng)前的索引
 *
 * @note 在每一層遞歸中,當(dāng)前的 中序遍歷 數(shù)組段 被分為:[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)
    {
        /// 從 前序遍歷 的數(shù)組中 獲取 當(dāng)前 根節(jié)點!
        T cur_root_val = pre_vec.at(pre_i);
        auto* cur_root = new Node<T>(cur_root_val);

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

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

        /// 一分為二!(注意,i是當(dāng)前節(jié)點的索引哦!)
        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;
    }

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

測試這段程序

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

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹


 

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹


上面這個是數(shù)字的,我現(xiàn)在拿字符串的試試:

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹


 

如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹


 

四種遍歷樹的方法的代碼

1.層序遍歷

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

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

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

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

         /// 如果右子節(jié)點非空就把右子節(jié)點放入隊列
         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);
    }
}

看完上述內(nèi)容,你們對如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

分享名稱:如何根據(jù)前序遍歷和中序遍歷創(chuàng)建python二叉樹
URL網(wǎng)址:http://www.chinadenli.net/article28/gogpjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機網(wǎng)站設(shè)計公司軟件開發(fā)標(biāo)簽優(yōu)化域名注冊動態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司