12.BFS與二叉搜索樹


Binary Tree BFS Traversal

二叉樹層次遍歷


//剛開始沒看懂衣屏,自己畫圖細看幾遍發(fā)生特別精妙,贊一個
//一定要記住隊列是先進先出的

void levelTraversal(TreeNode *root)
{
    queue<TreeNode *> nodeQueue;
    TreeNode *currentNode;
    if (!root) {
        return;
    }

    //先塞入根節(jié)點
    nodeQueue.push(root);

    while (!nodeQueue.empty()) {

        //當(dāng)前節(jié)點值為queue中的第一個數(shù)據(jù)恬口。
        currentNode = nodeQueue.front();

        //做進一步的處理者春,比如需要打印
        processNode(currentNode);
        if (currentNode->left) {
            nodeQueue.push(currentNode->left);
        }
        if (currentNode->right) {
            nodeQueue.push(currentNode->right);
        }

        //彈出當(dāng)前的數(shù)據(jù)
        nodeQueue.pop();
    }
}

Binary Tree to Linked Lists

Covert a binary tree to linked lists. Each linked list is correspondent to all the nodes at the same level.

核心問題:如何判斷這一層已經(jīng)遍歷完畢?

解題思路:利用優(yōu)先隊列

代碼示例:


//為什么你老是喜歡把你定義的result寫成answer,我真的要報警了

ool isDummyNode(TreeNode *node) {
    return (node->left == node);
}

vector<list<TreeNode *>> linkedListsFromTree(TreeNode *root) {
    vector<list<TreeNode *>> result;
    list<TreeNode *> levelList;
    queue<TreeNode *> nodeQueue;
    TreeNode *currentNode;

    TreeNode dummyNode;
    dummyNode.left = &dummyNode;


    if (!root) {
        return result;
    }

    nodeQueue.push(&dummyNode);//dummyNode用于分割層
    nodeQueue.push(root);

    while (!nodeQueue.empty()) {
        currentNode = nodeQueue.front();
        if (isDummyNode(currentNode)) {
            if (!levelList.empty()) {

                //若首節(jié)點時dummyNode且level不為空拍顷,就將該level塞入我們的最終結(jié)果列表
                //然后清空level正蛙。代表了一層遍歷的結(jié)束督弓,開始遍歷二叉樹的下一層
                result.push_back(levelList);
                levelList.clear();
            }
            nodeQueue.pop();
            if (nodeQueue.empty()) {
                break;
            } else {
                //每次遍歷完一層,nodeQueue都會被塞入一個dummyNode
                nodeQueue.push(&dummyNode);
            }

        } else {
            levelList.push_back(currentNode);
            if (currentNode->left) {
                nodeQueue.push(currentNode->left);
            }
            if (currentNode->right) {
                nodeQueue.push(currentNode->right);
            }
            nodeQueue.pop();
        }
    }

    return result;
}

Binary Tree Level Order Traversal

  • 2 Queues
  • 1 Queue + Dummy Node
  • 1 Queue (best)

示例代碼:


// use 2 variables 
//利用兩個變量來判斷一層是否遍歷完乒验,標(biāo)志位為nodesInCurrentLevel愚隧,
//當(dāng)其為0時一層遍歷結(jié)束,輸入endl換行
void printLevelOrder(BinaryTree *root) {
  if (!root) return;
  queue<BinaryTree*> nodesQueue;
  int nodesInCurrentLevel = 1;
  int nodesInNextLevel = 0;

  nodesQueue.push(root);
  while (!nodesQueue.empty()) {
    BinaryTree *currNode = nodesQueue.front();
    nodesQueue.pop();
    nodesInCurrentLevel--;
    if (currNode) {
      cout << currNode->data << " ";
      nodesQueue.push(currNode->left);
      nodesQueue.push(currNode->right);
      nodesInNextLevel += 2;
    }
    if (nodesInCurrentLevel == 0) {
      cout << endl;
      nodesInCurrentLevel = nodesInNextLevel;
      nodesInNextLevel = 0;
    }
  }
}

// use 2 queue
//使用隊列來判斷锻全,當(dāng)currentLevel時一層遍歷結(jié)束
void printLevelOrder(BinaryTree *root) {
  if (!root) return;
  queue<BinaryTree*> currentLevel, nextLevel;
  currentLevel.push(root);
  while (!currentLevel.empty()) {
    BinaryTree *currNode = currentLevel.front();
    currentLevel.pop();
    if (currNode) {
      cout << currNode->data << " ";
      nextLevel.push(currNode->left);
      nextLevel.push(currNode->right);
    }
    if (currentLevel.empty()) {
      cout << endl;
      swap(currentLevel, nextLevel);
    }
  }
}

Binary Tree Level Order Traversal II

Given a binary tree, return the bottom-up level order traversal of its nodes'values. (ie, from left to right, level by level from leaf to root).
For example: Given binary tree {3,9,20,#,#,15,7},

反式
反式

return its bottom-up level order traversal as:

反式1
反式1

Binary Tree Zigzag Level Order Traversal

原題地址

示例代碼:


void printLevelOrderZigZag(BinaryTree *root) {
  stack<BinaryTree*> currentLevel, nextLevel;
  bool leftToRight = true;
  currentLevel.push(root);
  while (!currentLevel.empty()) {
    BinaryTree *currNode = currentLevel.top();
    currentLevel.pop();
    if (currNode) {
      cout << currNode->data << " ";
      if (leftToRight) {
        nextLevel.push(currNode->left);
        nextLevel.push(currNode->right);
      } else {
        nextLevel.push(currNode->right);
        nextLevel.push(currNode->left);
      }
    }
    if (currentLevel.empty()) {
      cout << endl;
      leftToRight = !leftToRight;
      swap(currentLevel, nextLevel);
    }
  }
}

Binary Search Tree

二分查找樹(Binary Search Tree, BST)是二叉樹的一種特例奸攻,對于二分查找樹的任意節(jié)點蒜危,該節(jié)點儲存的數(shù)值一定比左子樹的所有節(jié)點的值大比右子樹的所有節(jié)點的值小(該節(jié)點儲存的數(shù)值一定比左子樹的所有節(jié)點的值小比右子樹的所有節(jié)點的值大)。基于這個特性匈辱,二分查找樹通常被用于維護有序數(shù)據(jù)扣汪。二分查找樹查找、刪除响委、插入的效率都會高于一般的線性數(shù)據(jù)結(jié)構(gòu)。

bst
bst

平衡二叉樹的概念窖梁。所謂平衡二叉樹赘风,是指一棵樹的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹纵刘。

有序數(shù)組變?yōu)槎植檎覙?/h3>

代碼示例:


TreeNode* helper(vector<int>num, int first, int last){
    if(first > last){
        return NULL;
    }
    if (first == last) {
        TreeNode* parent = new TreeNode(num[first]);
        return parent;
    }
    int mid = (first + last) / 2;
    TreeNode *leftchild = helper(num, first, mid - 1);
    TreeNode *rightchild = helper(num, mid + 1, last);
    TreeNode *parent = new TreeNode(num[mid]);
    parent->left = leftchild;
    parent->right = rightchild;
    return parent;
}

TreeNode *sortedArrayToBST(vector<int> &num) {
    if(num.size() == 0)
        return NULL;
    if(num.size() == 1){
        TreeNode* parent = new TreeNode(num[0]);
        return parent;
    }
    int first = 0;
    int last = (int)num.size() - 1;
    return helper(num, first, last);
}

Is Binary Search Tree

錯誤例子:


/************
    10  
    / \  
    5 15  
      / \  
     6  20  
*************/

bool isValidBST(TreeNode* root) {
    if(root==NULL)
        return true;
    else if(root->left&&!root->right)
        return isValidBST(root->left)&&(root->val>root->left->val);
    else if(!root->left&&root->right)
        return isValidBST(root->right)&&(root->val<root->right->val);
    else if(root->left&&root->right)
        return isValidBST(root->left)&&isValidBST(root->right)&&(root->val>root->left->val)&&(root->val<root->right->val);
    else
        return true;
}

正確示例


bool helper(TreeNode *root, int min, int max){
    if(!root) return true;
    if((root->val < max || (root->val == INT_MAX && root->right == NULL)) &&
        (root->val > min || (root->val == INT_MIN && root->left == NULL)) &&
        helper(root->left, min, root->val) &&
        helper(root->right, root->val, max))
          return true;
    return false;
}

bool isValidBST(TreeNode *root) {
    return helper(root, INT_MIN, INT_MAX);
}

Trie

字典樹(trie or prefix tree)是一個26(26個英文字母)叉樹邀窃,用于在一個集合中檢索一個字符串,或者字符串前綴假哎。字典樹的每個節(jié)點有一個指針數(shù)組代表其所有子樹瞬捕,其本質(zhì)上是一個hash table,因為子樹所在的位置(index)本身舵抹,就代表了節(jié)點對應(yīng)的字母肪虎。節(jié)點與每個兄弟具有相同的前綴,也被稱為prefix tree惧蛹。

Trie Structure


class TrieNode{
private:
    T mContent;
    vector<TrieNode*> mChildren;

public:
    Node();
    ~Node();
    friend class Trie;
};

class Trie{
public:
    Trie();
    ~Trie();
    void addWord(string s);
    bool searchWord(string s);
    void deleteWord(string s);

private:
    TrieNode* root;
};

Mock Interview

Lowest Common Ancestor(LCA)

最近的公共銜接點

Given a binary tree and two nodes. Find the lowest common ancestor of the two nodes in the tree.
For example, the LCA of D & E is B.

lca
lca

示例代碼:


TreeNode *commonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
    if (covers(root->left, p) && covers(root->left, q)) {
        return commonAncestor(root->left, q, p);
    }
    if (covers(root->right, p) && covers(root->right, q)) {
        return commonAncestor(root->right, q, p);
    }
    return root;
}

bool covers(TreeNode *root, TreeNode *p) {
    if (root == NULL) {
        return false;
    }
    if (root == p) {
        return true;
    }
    return covers(root->left, p) || covers(root->right, p);
}

// bottom to top

TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *A, TreeNode *B) {
        // return either A or B or NULL
        if (NULL == root || root == A || root == B) return root;

        TreeNode *left = lowestCommonAncestor(root->left, A, B);
        TreeNode *right = lowestCommonAncestor(root->right, A, B);

        // A and B are on both sides
        if ((NULL != left) && (NULL != right)) return root;

        // either left or right or NULL
        return (NULL != left) ? left : right;
    }

Homework:

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree is symmetric:


/************
     1  
   /   \  
  2     2  
 / \   / \  
3   4 4   3  

************/

But the following is not:

/**********
  1  
 / \  
 2  2  
  \  \  
   3  3  

**********/


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扇救,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子香嗓,更是在濱河造成了極大的恐慌迅腔,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靠娱,死亡現(xiàn)場離奇詭異沧烈,居然都是意外死亡,警方通過查閱死者的電腦和手機饱岸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門掺出,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人苫费,你說我怎么就攤上這事汤锨。” “怎么了百框?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵闲礼,是天一觀的道長。 經(jīng)常有香客問我,道長柬泽,這世上最難降的妖魔是什么慎菲? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮锨并,結(jié)果婚禮上露该,老公的妹妹穿的比我還像新娘。我一直安慰自己第煮,他們只是感情好解幼,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著包警,像睡著了一般撵摆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上害晦,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天特铝,我揣著相機與錄音,去河邊找鬼壹瘟。 笑死鲫剿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俐筋。 我是一名探鬼主播牵素,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼严衬,長吁一口氣:“原來是場噩夢啊……” “哼澄者!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起请琳,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤粱挡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俄精,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體询筏,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年竖慧,在試婚紗的時候發(fā)現(xiàn)自己被綠了嫌套。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡圾旨,死狀恐怖踱讨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情砍的,我是刑警寧澤痹筛,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響帚稠,放射性物質(zhì)發(fā)生泄漏谣旁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一滋早、第九天 我趴在偏房一處隱蔽的房頂上張望榄审。 院中可真熱鬧,春花似錦杆麸、人聲如沸瘟判。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拷获。三九已至,卻和暖如春减细,著一層夾襖步出監(jiān)牢的瞬間匆瓜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工未蝌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驮吱,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓萧吠,卻偏偏與公主長得像左冬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纸型,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容