二叉樹遍歷操作匯總

前序遍歷

對根節(jié)點,左右子樹采取根左右的順序進行遍歷。

遞歸

void preorderTraversal(TreeNode* root) {
  if(!root) return ;
   visit(root);
  preorderTraversal(root->left);
  preorderTraversal(root->right);
}

非遞歸

    vector<int> preorderTraversal(TreeNode* root) {
       vector<int>res;
       stack<TreeNode*>s;//使用棧來存儲節(jié)點
       auto p=root;
       while(p||!s.empty()){//二者有一個滿足循環(huán)就可以繼續(xù)
            while(p){ //先訪問根節(jié)點,訪問完之后再入棧
                res.push_back(p->val);
                s.push(p);
                p=p->left;
            }
            p=s.top();
            s.pop();
            //彈出棧頂結(jié)點,開始遍歷其右子樹
            p=p->right;
       }
       return res;
    }

中序遍歷

左根右的順序

遞歸

void inorderTraversal(TreeNode* root) {
  if(!root) return ;
  inorderTraversal(root->left);
  visit(root);
  inorderTraversal(root->right);
}

非遞歸

  vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> ss;
        auto p=root;
        while(!ss.empty()||p){
            while(p){
                 ss.push(p);
                p=p->left;
            }
            p=ss.top();
            ss.pop();
            res.push_back(p->val);  //對根節(jié)點的訪問放在其左子樹之后,前序和中序的區(qū)別就在這里。
            p=p->right;
        }
        return res;
    }

后序遍歷

左右根的順序

遞歸

void postorderTraversal(TreeNode* root) {
  if(!root) return ;
  postorderTraversal(root->left);
  postorderTraversal(root->right);
   visit(root);
}

非遞歸

后序遍歷比起前兩種又復(fù)雜一點點,因為你在訪問到根節(jié)點的時候無法判斷它的右子樹是否已經(jīng)遍歷完,

  vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> ss;
        auto p=root;
        TreeNode* pre=nullptr;//設(shè)置一個前置指針,指向遍歷的上一個結(jié)點
        while(!ss.empty()||p){
            while(p){
                 ss.push(p);
                p=p->left;
            }
            p=ss.top();
          if(p->right==nullptr||p->right==pre){ //在這里判斷右子樹有沒有遍歷完畢,若已遍歷完,則訪問當(dāng)前節(jié)點。
              res.push_back(p->val);
              ss.pop();
              pre=p;
              p=nullptr;//p指針需要置空,確保循環(huán)可以正確退出
          }
           else  
            p=p->right;
        }
        return res;
    }

層次遍歷

對同一層次的結(jié)點,從左至右依次輸出,使用隊列很方便

一次性遍歷

    vector<int> levelOrder(Node* root) {
        vector<int>res;
      if(!root) return res;
       queue<Node*>q;
       Node *t;
       q.push(root);
       while(!q.empty()){
               t=q.front(); 
               q.pop();
          res.push_back(t->val);
         if(t->left) q.push(t->left);
         if(t->right) q.push(t->right);
    }
       return res;     
    }

分層遍歷,也就是要把每一層分開

  vector<vector<int>> levelOrder(TreeNode* root) { //返回一個二維數(shù)組
        vector<vector<int>>res;
                if(!root) return res;
        queue<TreeNode*>q;
        q.push(root);
        int levelnum=0;//下一層結(jié)點的數(shù)目
        int level=1;//當(dāng)前層節(jié)點的數(shù)目
        vector<int>temp;
      while(!q.empty()){
        if(level==0){//這是核心代碼,遍歷完一層后將下一層數(shù)量轉(zhuǎn)移給level,levelnum重新計數(shù)
            res.push_back(temp);
            temp.clear();
            level=levelnum;
            levelnum=0;
        }
        TreeNode* node=q.front();
        q.pop();
        if(node->left) {
          q.push(node->left);
          levelnum++;
        }
        if(node->right){
             q.push(node->right);
             levelnum++;
        }
         temp.push_back(node->val);
         level--;
      }
      if(level==0) res.push_back(temp);
      return res;
    }

根據(jù)前序遍歷與中序遍歷來確定該二叉樹

前序遍歷第一個節(jié)點是根節(jié)點,則中序遍歷中對應(yīng)節(jié)點之前的即為左子樹,之后的為右子樹。 然后遞歸著來還原這棵樹就行。
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int l=preorder.size();
      if(l==0) return NULL;
       return postorder(preorder,0,l-1,inorder,0,l-1);
    }
  TreeNode*  postorder(vector<int>& preorder,int ps,int pe,vector<int>& inorder,int is,int ie){
        TreeNode* p=new TreeNode(preorder[ps]);
        int i=is;
        while(preorder[ps]!=inorder[i])  i++;
        int left=i-is;
        int right=ie-i;
        if(left>0) p->left=postorder(preorder,ps+1,ps+left,inorder,is,i-1);
        if(right>0) p->right=postorder(preorder,ps+left+1,pe,inorder,i+1,ie);
        return p;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容