【二叉樹】二叉樹常用算法的C++實現


常見算法有:

1.求二叉樹的最大深度

2.求二叉樹的最小深度

3.二叉樹的層次遍歷

4.二叉樹的前序遍歷

5.二叉樹的中序遍歷

6.二叉樹的后序遍歷

7.求二叉樹的節點個數

8.求二叉樹的葉節點個數

9.判斷二叉樹是否為平衡二叉樹

10.判斷二叉樹是否為滿二叉樹

11.判斷兩個二叉樹是否完全相同

12.判斷二叉樹是否為二叉搜索樹

13.將有序數組轉換為二叉搜索樹

14.鏡像翻轉二叉樹

15.二叉樹的“之”字形遍歷

16.判斷兩個二叉樹是否互為鏡像

17.判斷一個二叉樹本身是否為鏡像二叉樹(對稱二叉樹)

18.求兩個節點最近的公共祖先

19.判斷兩個節點是否為堂兄弟(深度相同且父節點不同)

(涉及到的相關概念不再累述)

0.二叉樹結構體定義

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

1.求二叉樹的最大深度

int maxDepth(TreeNode* root){
    if (root == NULL)  return 0;
    int left = maxDepth(root->left);
    int right = maxDepth(root->right);
    return max(left, right) + 1;
}

 

2.求二叉樹的最小深度

int minDepth(TreeNode* root){
    if (root == NULL)  return 0;
    return getMin(root);
}
int getMin(TreeNode* root){
    if (root == NULL)  return INT_MAX;
    if (root->left == NULL && root->right == NULL)  return 1;
    return min(getMin(root->left), getMin(root->right)) + 1;
}

 

3.二叉樹的層次遍歷

 
         
void levelView(TreeNode* root){
    vector<int> s; queue<TreeNode*> p, q; p.push(root);
q = p; while (!p.empty()){ p = queue<TreeNode*>(); s.clear(); while (!q.empty()){ TreeNode* tmp = q.front(); q.pop(); s.push_back(tmp->val); if (tmp->left != NULL) p.push(tmp->left); if (tmp->right != NULL) p.push(tmp->right); } for (auto i : s) cout << i << " "; cout << endl; q = p; } }

4.二叉樹的前序遍歷

void preView(TreeNode* root){
    if (root != NULL){
        cout << root->val << " ";
        preView(root->left);
        preView(root->right);
    }
}

 

5.二叉樹的中序遍歷

void midView(TreeNode* root){
    if (root != NULL){
        midView(root->left);
        cout << root->val << " ";
        midView(root->right);
    }
}

 

6.二叉樹的后序遍歷

void postView(TreeNode* root){
    if (root != NULL){
        postView(root->left);
        postView(root->right);
        cout << root->val << " ";
    }
}

 

7.求二叉樹的節點個數

int nodeNumbers(TreeNode* root){
    if (root == NULL)  return 0;
    int left = nodeNumbers(root->left);
    int right = nodeNumbers(root->right);
    return left + right + 1;
}

 

8.求二叉樹的葉節點個數

int leafNodeNumbers(TreeNode* root){
    if (root == NULL)  return 0;
    if (root->left == NULL && root->right == NULL)  return 1;
    return leafNodeNumbers(root->left) + leafNodeNumbers(root->right);
}

 

9.判斷二叉樹是否為平衡二叉樹

int countFloor(TreeNode* root){//計算層數
    if (!root)  return 0;
    return 1 + max(countFloor(root->left), countFloor(root->right));
}
bool isBalanced(TreeNode* root) {
    if (!root)  return true;
    if (abs(countFloor(root->left) - countFloor(root->right)) > 1)  return false;
    else  return isBalanced(root->left) && isBalanced(root->right);
}

 

10.判斷二叉樹是否為滿二叉樹

bool isFullTree(TreeNode* root){
    if (root == NULL)  return true;
    int n = nodeNumbers(root) + 1;//滿二叉樹節點數為2^n-1,利用算法7求節點數
    while (n > 1){
        if (n % 2 == 1)  return false;
        n /= 2;
    }
    return true;
}

 

11.判斷兩個樹是否完全相同

bool isSameTree(TreeNode* p, TreeNode* q) {
    if (!p && !q) return true;
    if (q != NULL && p != NULL){
        if (q->val != p->val) return false;
        else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    } else
        return false;
}

 

12.判斷二叉樹是否為二叉搜索樹

void midView(TreeNode* p, vector<int> &s){
    if (p){
        midView(p->left, s);
        s.push_back(p->val);
        midView(p->right, s);
    }
}
bool isValidBST(TreeNode* root) {
    vector<int> s;
    midView(root, s);
    if (s.size() < 2)  return true;
    for (int i = 0; i < s.size() - 1; i++){
        if (s[i] >= s[i + 1])  return false;
    }
    return true;
}

 

13.將有序數組轉換為二叉搜索樹

TreeNode* buildTree(vector<int> &num, int left, int right) {
    if (left > right) return NULL;
    int mid = (left + right) / 2;
    TreeNode* cur = new TreeNode(num[mid]);
    cur->left = buildTree(num, left, mid - 1);
    cur->right = buildTree(num, mid + 1, right);
    return cur;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
    return buildTree(nums, 0, nums.size() - 1);
}

 

14.鏡像翻轉二叉樹

TreeNode* invertTree(TreeNode* root) {
    if (root != NULL){
        TreeNode *tmp = root->left;
        root->left = root->right;
        root->right = tmp;
        invertTree(root->left);
        invertTree(root->right);
    }
    return root;
}

 

15.二叉樹之字形遍歷(第一層從左往右遍歷,第二層從右往左遍歷,第三次從左往右…)

vector<vector<int> > zigzagLevelOrder(TreeNode* root) {
    vector<vector<int> > s;
    bool change = false;
    if (root == NULL)  return s;
    queue<TreeNode*> p;
    p.push(root);
    vector<int> t;
    queue<TreeNode*> q = p;
    t.push_back(root->val);
    while (!q.empty()){
        q = queue<TreeNode*>();
        t.clear();
        while (!p.empty()){
            TreeNode* tmp = p.front();
            t.push_back(tmp->val);
            p.pop();
            if (tmp->left != NULL)  q.push(tmp->left);
            if (tmp->right != NULL)  q.push(tmp->right);
        }
        p = q;
        if (change){
            change = false;
            reverse(t.begin(), t.end());
        } else  change = true;
        s.push_back(t);
    }
    return s;
}

 

16.判斷兩個二叉樹是否互為鏡像

bool isMirror(TreeNode* p, TreeNode* q){
    if (p == NULL && q == NULL)  return true;
    if (p == NULL || q == NULL)  return false;
    if (p->val != q->val)  return false;
    return isMirror(p->left, q->right) && isMirror(p->right, q->left);
}

 

17.判斷二叉樹本身是否為鏡像二叉樹

bool isMirrorTree(TreeNode* root){
    return isMirror(root, root);//利用算法16,如果一個樹是鏡像的,那么它和自己本身互為鏡像
}

 

18.求二叉樹中兩個節點的最近公共祖先

void help(TreeNode* p, map<TreeNode*, TreeNode*> &q){
    if (p){
        if (p->left)  q[p->left] = p;
        if (p->right)  q[p->right] = p;
        help(p->left, q);
        help(p->right, q);
    }
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    map<TreeNode*, TreeNode*> m;
    TreeNode* head = root;
    help(root, m);
    if (m[p] == q)  return q;
    if (m[q] == p)  return p;
    while (p != head){
        TreeNode* tmp = q;
        while (tmp != head){
            if (p == tmp || m[tmp] == p)  return p;
            if (m[p] == tmp)  return tmp;
            tmp = m[tmp];
        }
        p = m[p];
    }
    return head;
}

 

19.判斷二叉樹中兩個節點是否為堂兄弟(深度相同但父節點不同)

void help(TreeNode *root, map<int, int> &p){
    if (root != NULL){
        if (root->left != NULL)  p[root->left->val] = root->val;
        if (root->right != NULL)  p[root->right->val] = root->val;
        help(root->left, p);
        help(root->right, p);
    }
}
map<int, int> p;
bool isCousins(TreeNode* root, int x, int y) {
    help(root, p);
    if (p[x] == 0 || p[y] == 0)  return false;
    if (p[x] == p[y])  return false;
    int xi = 0, yi = 0;
    while (p[x] != p[y]){
        if (p[p[x]] != 0){
            x = p[x];
            xi++;
        }
        if (p[p[y]] != 0){
            y = p[y];
            yi++;
        }
    }
    return xi == yi;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM