劍指Offer-從上到下打印二叉樹(shù)

1. 題目 1

不分行從上到下打印二叉樹(shù)虱颗。從上到下打印出二叉樹(shù)的每個(gè)結(jié)點(diǎn)诚些,同一層的結(jié)點(diǎn)按照從左到右的順序打印汤踏。

1.1 示例

輸入:

     8
    / \
   6   10
  / \  / \
 5   7 9  11

輸出:

8 6 10 5 7 9 11

1.2 解題思路

這個(gè)其實(shí)就是層序遍歷涝涤。每次打印一個(gè)結(jié)點(diǎn)的時(shí)候,若該結(jié)點(diǎn)有子結(jié)點(diǎn)淫僻,則讓該結(jié)點(diǎn)的子結(jié)點(diǎn)放到一個(gè)隊(duì)列的末尾诱篷。接下來(lái)到隊(duì)列的首部取出最早進(jìn)入隊(duì)列的結(jié)點(diǎn),不斷重復(fù)前面的打印嘁傀,直至隊(duì)列中所有的結(jié)點(diǎn)都被打印出來(lái)兴蒸。

1.3 代碼實(shí)現(xiàn)

#include <iostream>
#include <vector>
#include <queue>

struct BiTNode {
    int val;
    BiTNode* left;
    BiTNode* right;
    BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    std::vector<int> PrintFromTopToBottom(BiTNode* root) {
        // 存儲(chǔ)打印結(jié)果
        std::vector<int> result;
        
        // 邊界條件
        if (root == nullptr) {
            return result;
        }
        
        // 輔助容器:隊(duì)列
        std::queue<BiTNode*> qeueTreeNode;
        
        // 根結(jié)點(diǎn)入隊(duì)
        qeueTreeNode.push(root);
        
        // 遍歷隊(duì)列
        while (!qeueTreeNode.empty()) {
            // 輔助指針:指向隊(duì)頭
            BiTNode* node = qeueTreeNode.front();

            // 打印結(jié)果存儲(chǔ)到result中
            result.push_back(node->val);
            
            // 根結(jié)點(diǎn)的子結(jié)點(diǎn)入隊(duì)
            if (node->left != nullptr) {
                qeueTreeNode.push(node->left);
            }
            if (node->right != nullptr) {
                qeueTreeNode.push(node->right);
            }

            // 根結(jié)點(diǎn)出隊(duì)
            qeueTreeNode.pop();
        }
        
        return result;
    }
};

// 銷毀二叉樹(shù)
void DestroyBiTree(BiTNode* root)
{
    if (root == nullptr) {
        return;
    }

    DestroyBiTree(root->left);
    DestroyBiTree(root->right);

    // 從最左依次 delete 至根結(jié)點(diǎn)
    delete root;
    root = nullptr;        
}

int main(void)
{
    Solution sol;
    std::vector<int> res;
    
    // 構(gòu)造一個(gè)二叉樹(shù)
    BiTNode* root = new BiTNode(8);
    root->left = new BiTNode(6);
    root->right = new BiTNode(10);
    root->left->left = new BiTNode(5);
    root->left->right = new BiTNode(7);
    root->right->left = new BiTNode(9);
    root->right->right = new BiTNode(11);
    
    res = sol.PrintFromTopToBottom(root);
    
    // 遍歷vector,C++ 11 標(biāo)準(zhǔn)支持
    for (int i:res) {
         std::cout << i;
         
        if (i != res[res.size() - 1]) {
            std::cout << ' ';
        }
    }
    
    // 遍歷vector细办,打印結(jié)果
    // for (unsigned int i = 0; i < res.size(); ++i) {
    //     std::cout << res[i];
    //     if (i != res.size() - 1) {
    //         std::cout << ' ';
    //     }
    // }
    std::cout << std::endl;

    DestroyBiTree(root);
    
    return 0;
}

2. 題目 2

分行從上到下打印二叉樹(shù)橙凳。從上到下按層打印二叉樹(shù),同一層的結(jié)點(diǎn)按從左到右的順序打印笑撞,每一層打印到一行岛啸。

2.1 示例

輸入:

     8
    / \
   6   10
  / \  / \
 5   7 9  11

輸出:

8
6 10
5 7 9 11

2.2 解題思路

為了把二叉樹(shù)的每一行單獨(dú)打印到一行里,我們需要兩個(gè)變量:一個(gè)變量表示當(dāng)前層中還未打印的結(jié)點(diǎn)數(shù)茴肥;另一個(gè)變量表示下一層結(jié)點(diǎn)的數(shù)目坚踩。

2.3 代碼實(shí)現(xiàn)

#include <iostream>
#include <queue>

struct BiTNode {
    int val;
    BiTNode* left;
    BiTNode* right;
    BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    int PrintTreesInLines(BiTNode* root) {
 
        // 邊界條件
        if (root == nullptr) {
            return -1;
        }

        std::queue<BiTNode*> qeueTreeNode;

        qeueTreeNode.push(root);

        // 下一層的結(jié)點(diǎn)數(shù)
        int nextLevel = 0;

        // 當(dāng)前層中未打印的結(jié)點(diǎn)數(shù)
        int toBePrinted = 1;

        while (!qeueTreeNode.empty()) {
            BiTNode* node = qeueTreeNode.front();
            
            // 打印結(jié)果
            std::cout << node->val;

            // 打印結(jié)果之間用空格隔開(kāi)
            if (toBePrinted != 1) {
                std::cout << ' ';
            }

            if (node->left != nullptr) {
                qeueTreeNode.push(node->left);
                ++nextLevel;
            }
            if (node->right != nullptr) {
                qeueTreeNode.push(node->right);
                ++nextLevel;
            }

            qeueTreeNode.pop();
            --toBePrinted;
            
            // 當(dāng)前層的所有結(jié)點(diǎn)已打印完畢,可以繼續(xù)打印下一層
            if (toBePrinted == 0) {
                std::cout << std::endl;
                toBePrinted = nextLevel;
                nextLevel = 0;
            }
        }
        
        return 0;
    }
};

// 銷毀二叉樹(shù)
void DestroyBiTree(BiTNode* root)
{
    if (root == nullptr) {
        return;
    }

    DestroyBiTree(root->left);
    DestroyBiTree(root->right);

    // 從最左依次 delete 至根結(jié)點(diǎn)
    delete root;
    root = nullptr;        
}

int main(void)
{
    Solution sol;
    
    // 構(gòu)造一個(gè)二叉樹(shù)
    BiTNode* root = new BiTNode(8);
    root->left = new BiTNode(6);
    root->right = new BiTNode(10);
    root->left->left = new BiTNode(5);
    root->left->right = new BiTNode(7);
    root->right->left = new BiTNode(9);
    root->right->right = new BiTNode(11);
    
    sol.PrintTreesInLines(root);

    std::cout << std::endl;
    
    DestroyBiTree(root);
    
    return 0;
}

3. 題目 3

之字形打印二叉樹(shù)瓤狐。請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù)按照之字形順序打印二叉樹(shù)瞬铸,即第一行按照從左到右的順序打印,第二行按照從右到左的順序打印础锐,第三行再按照從左到右的順序打印嗓节,其它行以此類推。

3.1 示例

輸入:

          1
       /      \
    2           3
   / \        /   \
  4    5     6     7
/  \  /  \   / \  / \
8  9  10 11 12 13 14 15

輸出:

1
3 2
4 5 6 7
15 14 13 12 11 10 9 8

3.2 解題思路

按之字形順序打印二叉樹(shù)需要兩個(gè)棧皆警。在打印某一層的結(jié)點(diǎn)時(shí)拦宣,把下一層的子結(jié)點(diǎn)保存到相應(yīng)的棧里。若當(dāng)前打印的是奇數(shù)層(第 1 、3 層等)鸵隧,則先保存左子結(jié)點(diǎn)再保存右子結(jié)點(diǎn)到第一個(gè)棧里绸罗;若打印的是偶數(shù)層(第 2 、4層等)豆瘫,則先保存右子結(jié)點(diǎn)再保存左子結(jié)點(diǎn)到第二個(gè)棧里珊蟀。

3.3 代碼實(shí)現(xiàn)

#include <iostream>
#include <stack>

struct BiTNode {
    int val;
    BiTNode* left;
    BiTNode* right;
    BiTNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    int PrintTreesInZigzag(BiTNode* root) {
 
        // 邊界條件
        if (root == nullptr) {
            return -1;
        }

        std::stack<BiTNode*> stackLevels[2];

        int current = 0;
        int next = 1;

        stackLevels[current].push(root);

        while (!stackLevels[0].empty() || !stackLevels[1].empty()) {
            BiTNode* node = stackLevels[current].top();
            stackLevels[current].pop();

            std::cout << node->val;

            if (!stackLevels[current].empty()) {
                std::cout << ' ';
            }

            if (current == 0) {
                if (node->left != nullptr) {
                    stackLevels[next].push(node->left);
                }
                if (node->right != nullptr) {
                    stackLevels[next].push(node->right);
                }
            } else {
                if (node->right != nullptr) {
                    stackLevels[next].push(node->right);
                }
                if (node->left != nullptr) {
                    stackLevels[next].push(node->left);
                }
            }

            if (stackLevels[current].empty()) {
                std::cout << std::endl;
                current = 1 - current;
                next = 1 - next;
            }
        }
        
        return 0;
    }
};

// 銷毀二叉樹(shù)
void DestroyBiTree(BiTNode* root)
{
    if (root == nullptr) {
        return;
    }

    DestroyBiTree(root->left);
    DestroyBiTree(root->right);

    // 從最左依次 delete 至根結(jié)點(diǎn)
    delete root;
    root = nullptr;        
}

int main(void)
{
    Solution sol;
    
    // 構(gòu)造一個(gè)二叉樹(shù)
    BiTNode* root = new BiTNode(1);
    root->left = new BiTNode(2);
    root->right = new BiTNode(3);
    root->left->left = new BiTNode(4);
    root->left->right = new BiTNode(5);
    root->right->left = new BiTNode(6);
    root->right->right = new BiTNode(7);
    root->left->left->left = new BiTNode(8);
    root->left->left->right = new BiTNode(9);
    root->left->right->left = new BiTNode(10);
    root->left->right->right = new BiTNode(11);
    root->right->left->left = new BiTNode(12);
    root->right->left->right = new BiTNode(13);
    root->right->right->left = new BiTNode(14);
    root->right->right->right = new BiTNode(15);
    
    sol.PrintTreesInZigzag(root);

    std::cout << std::endl;
    
    DestroyBiTree(root);
    
    return 0;
}

個(gè)人主頁(yè):

www.codeapes.cn

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市靡羡,隨后出現(xiàn)的幾起案子系洛,更是在濱河造成了極大的恐慌俊性,老刑警劉巖略步,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異定页,居然都是意外死亡趟薄,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門典徊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)杭煎,“玉大人,你說(shuō)我怎么就攤上這事卒落∠鄄” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵儡毕,是天一觀的道長(zhǎng)也切。 經(jīng)常有香客問(wèn)我,道長(zhǎng)腰湾,這世上最難降的妖魔是什么雷恃? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮费坊,結(jié)果婚禮上倒槐,老公的妹妹穿的比我還像新娘。我一直安慰自己附井,他們只是感情好讨越,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著永毅,像睡著了一般把跨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卷雕,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天节猿,我揣著相機(jī)與錄音,去河邊找鬼。 笑死滨嘱,一個(gè)胖子當(dāng)著我的面吹牛峰鄙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播太雨,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吟榴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了囊扳?” 一聲冷哼從身側(cè)響起吩翻,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锥咸,沒(méi)想到半個(gè)月后狭瞎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搏予,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年熊锭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雪侥。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碗殷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出速缨,到底是詐尸還是另有隱情锌妻,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布旬牲,位于F島的核電站仿粹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏引谜。R本人自食惡果不足惜牍陌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望员咽。 院中可真熱鬧毒涧,春花似錦、人聲如沸贝室。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滑频。三九已至捡偏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間峡迷,已是汗流浹背银伟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工你虹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人彤避。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓傅物,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親琉预。 傳聞我的和親對(duì)象是個(gè)殘疾皇子董饰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354