常見算法有:
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; }
