最早的c2c網站seo網絡推廣專員
二叉樹定義
以下為本文解題代碼的二叉樹定義。
struct TreeNode {int val;TreeNode* left, *right;TreeNode(int val = 0, TreeNode* left = nullptr, TreeNode* right = nullptr): val(val), left(left), right(right) {}
};
非遞歸后序遍歷
題目描述
編寫后序遍歷二叉樹的非遞歸算法。
解題代碼
void nonRecurPost(TreeNode* root) {if (root == nullptr) return;stack<TreeNode*> s;TreeNode* pre = nullptr;while (root != nullptr || !s.empty()) {while (root != nullptr) {s.emplace(root);root = root->left;}root = s.top();s.pop();if (root->right == nullptr || root->right == pre) {cout << root->val << " ";pre = root;root = nullptr;}else {s.emplace(root);root = root->right;}}
}
反向層序遍歷
題目描述
試給出二叉樹的自下而上、從右到左的層序遍歷算法。
解題代碼
void reOrderTraversal(TreeNode* root) {queue<TreeNode*> Q;stack<int> S;Q.emplace(root);while (!Q.empty()) {TreeNode* fNode = Q.front();S.emplace(fNode->val);Q.pop();if (fNode->left != nullptr) {Q.emplace(fNode->left);}if (fNode->right != nullptr) {Q.emplace(fNode->right);}}while (!S.empty()) {cout << S.top() << " ";S.pop();}
}
非遞歸計算高度
題目描述
假設二叉樹采用二叉鏈表存儲結構,設計一個非遞歸算法求二叉樹的高度。
解題代碼
int nonRecurHeight(TreeNode* root) {if (root == nullptr) return 0;int res = 0;queue<TreeNode*> q, nq;q.emplace(root);while (!q.empty()) {while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left != nullptr) {nq.emplace(fNode->left);}if (fNode->right != nullptr) {nq.emplace(fNode->right);}}q = move(nq);++res;}return res;
}
根據中序和先序序列建立二叉樹
題目描述
設一棵二叉樹各結點的值互不相同,其先序遍歷序列和中序遍歷序列分別存儲于兩個一維數組 A 和 B 中,試編寫算法建立該二叉樹的二叉鏈表。
解題代碼
TreeNode* recurCreate(vector<int>& preOrder, int l1, int r1, vector<int>& inOrder, int l2, int r2) {if (l1 == r1) return nullptr;auto preBegin = preOrder.begin() + l1, preEnd = preOrder.begin() + r1;auto inBegin = inOrder.begin() + l2, inEnd = inOrder.begin() + r2;int x = *preBegin;TreeNode* root = new TreeNode(x);auto it = find(inBegin, inEnd, x);int lenL = it - inBegin;root->left = recurCreate(preOrder, l1 + 1, l1 + lenL + 1, inOrder, l2, l2 + lenL);root->right = recurCreate(preOrder, l1 + lenL + 1, r1, inOrder, l2 + lenL + 1, r2);return root;}TreeNode* createTree(vector<int>& preOrder, vector<int>& inOrder) {int l1 = 0, r1 = preOrder.size();int l2 = 0, r2 = inOrder.size();return recurCreate(preOrder, l1, r1, inOrder, l2, r2);}
判斷完全二叉樹
題目描述
二叉樹按二叉鏈表形式存儲,試編寫一個判別給定二叉樹是否是完全二叉樹的算法。
解題代碼
bool isCompleteBT(TreeNode* root) {queue<TreeNode*> Q;Q.emplace(root);bool isLeaves = false;while (!Q.empty()) {TreeNode* fNode = Q.front();Q.pop();if (fNode == nullptr) {isLeaves = true;continue;}if (isLeaves) return false;Q.emplace(fNode->left);Q.emplace(fNode->right);}return true;
}
計算雙分支結點數
題目描述
假設二叉樹采用二叉鏈表存儲結構存儲,試設計一個算法,計算一棵給定二叉樹的所有雙分支結點個數。
解題代碼
int doubleNodeCnt(TreeNode* root) {if (root == nullptr) return 0;if (root->left != nullptr && root->right != nullptr) {return 1 + doubleNodeCnt(root->left) + doubleNodeCnt(root->right);}else {return doubleNodeCnt(root->left) + doubleNodeCnt(root->right);}
}
交換左右子樹
題目描述
設樹 B 是一棵采用鏈式結構存儲的二叉樹,編寫一個把樹 B 中所有結點的左右子樹進行交換的算法。
解題代碼
void swapLRNode(TreeNode* root) {if (root == nullptr) return;TreeNode* temp = root->left;root->left = root->right;root->right = temp;swapLRNode(root->left);swapLRNode(root->right);
}
先序序列第k個結點值
題目描述
假設二叉樹采用二叉鏈表存儲結構,設計一個算法,求先序遍歷序列中第 k (1 <= k <= 鏈表中結點個數)個結點的值。
解題代碼
int kthNodeVal(TreeNode* root, int& k) {if (root == nullptr) return 0;if (--k == 0) return root->val;return kthNodeVal(root->left, k) + kthNodeVal(root->right, k);
}
刪除特定值的結點的子樹
題目描述
已知二叉樹以二叉鏈表形式存儲,編寫算法完成:對于樹中的每個元素值為 x 的結點,刪除以它為根的子樹,并釋放相應的空間。
解題代碼
void freeMemory(TreeNode* root) {if (root == nullptr) return;freeMemory(root->left);freeMemory(root->right);delete root;
}void deleteXNode(TreeNode* root, int x) {if (root == nullptr) return;else if (root->val == x) {freeMemory(root);return;}if (root->left != nullptr && root->left->val == x) {freeMemory(root->left);root->left = nullptr;}if (root->right != nullptr && root->right->val == x) {freeMemory(root->right);root->right = nullptr;}deleteXNode(root->left, x);deleteXNode(root->right, x);
}
值為x的結點的祖先
題目描述
在二叉樹中查找值為 x 的結點,試編寫算法打印值為 x 的結點的所有祖先,假設值為 x 的結點的不多于一個。
解題代碼
bool ancestorOfXNode(TreeNode* root, int x) {if (root == nullptr) return false;if (root->val == x) return true;bool left = ancestorOfXNode(root->left, x);bool right = ancestorOfXNode(root->right, x);if (left || right) {cout << root->val << " ";}return left || right;
}
兩結點的最近公共祖先
題目描述
設 p 和 q 為指向二叉樹中任意兩個結點的指針,試編寫算法找到 p 和 q 的最近公共祖先結點 r.
解題代碼
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == nullptr || root == p || root == q) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);if (left != nullptr && right != nullptr) {return root;}else if (left != nullptr) {return left;}else {return right;}
}
二叉樹的寬度
題目描述
假設二叉樹采用二叉鏈表存儲結構,設計一個算法,求非空二叉樹 b 的寬度(即具有結點數最多的那一層的結點個數)。
解題代碼
int widthOfBT(TreeNode* root) {if (root == nullptr) return 0;size_t res = 1;queue<TreeNode*> q, nq;q.emplace(root);while (!q.empty()) {while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left != nullptr) {nq.emplace(fNode->left);}if (fNode->right != nullptr) {nq.emplace(fNode->right);}}q = move(nq);res = max(res, q.size());}return res;
}
滿二叉樹的后序序列
題目描述
設有一棵滿二叉樹(所有結點值均不同),已知其先序序列為 pre,設計一個算法求其后序序列 post.
解題代碼
void getPost(vector<int>& preOrder, int p1, int q1, vector<int>& postOrder, int p2, int q2) {if (p1 > q1) return;postOrder[q2] = preOrder[p1];int mid = (q1 - p1) / 2;getPost(preOrder, p1 + 1, p1 + mid, postOrder, p2, p2 + mid - 1);getPost(preOrder, p1 + mid + 1, q1, postOrder, p2 + mid, q2 - 1);
}vector<int> postOfFBT(vector<int>& preOrder) {int n = preOrder.size();vector<int> res(n);getPost(preOrder, 0, n - 1, res, 0, n - 1);return res;
}
將葉結點連接為單鏈表
題目描述
設計一個算法將二叉樹的葉結點按從左到右的順序連成一個單鏈表,表頭指針為 head,二叉樹按照二叉鏈表形式存儲。
解題代碼
ListNode* linkingLeaves(TreeNode* root) {queue<TreeNode*> q;q.emplace(root);ListNode* dummy = new ListNode(-1);ListNode* curNode = dummy;while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left == nullptr && fNode->right == nullptr) {curNode->next = new ListNode(fNode->val);curNode = curNode->next;}if (fNode->left != nullptr) {q.emplace(fNode->left);}if (fNode->right != nullptr) {q.emplace(fNode->right);}}return dummy->next;
}
相似二叉樹
題目描述
試設計判斷兩棵二叉樹是否相似的算法。所謂二叉樹 T1 和 T2 相似,指的是 T1 和 T2 都是空的二叉樹或都只有一個根節(jié)點;或者 T1 的左子樹和 T2 的左子樹是相似的,且 T1 的右子樹和 T2 的右子樹是相似的。
解題代碼
bool similarBT(TreeNode* root1, TreeNode * root2) {if (root1 == nullptr && root2 == nullptr) return true;if ((root1 == nullptr) ^ (root2 == nullptr)) return false;if (root1->left == nullptr && root1->right == nullptr && root2->left == nullptr && root2->right == nullptr) {return true;}return similarBT(root1->left, root2->left) && similarBT(root1->right, root2->right);
}
二叉樹的帶權路徑長度和
題目描述
二叉樹的帶權路徑長度(WPL)是二叉樹中所有葉結點的帶權路徑長度之和,給定一棵二叉樹,其葉結點的 val 域保存該結點的非負權值。設 root 為指向 T 的根節(jié)點的指針,設計求 T 的 WPL 的算法。
解題代碼
BFS
int getWPL(TreeNode* root) {queue<TreeNode*> q, nq;q.emplace(root);int res = 0;for (int len = 0; !q.empty(); ++len) {while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode->left == nullptr && fNode->right == nullptr) {res += fNode->val * len;}if (fNode->left != nullptr) {nq.emplace(fNode->left);}if (fNode->right != nullptr) {nq.emplace(fNode->right);}}q = move(nq);}return res;
}
DFS
int dfs(TreeNode* root, int depth) {if (root == nullptr) return 0;if (root->left == nullptr && root->right == nullptr) {return root->val * depth;}return dfs(root->left, depth + 1) + dfs(root->right, depth + 1);
}int getWPL(TreeNode* root) {return dfs(root, 0);
}
表達式樹轉表達式
題目描述
請設計一個算法,將給定表達式樹轉換為對應的中綴表達式并輸出。
解題代碼
void dfs(TreeNode<char>* root, int depth) {if (root == nullptr) return;if (root->left == nullptr && root->right == nullptr) {cout << root->val;}else {if (depth > 1) cout << "(";dfs(root->left, depth + 1);cout << root->val;dfs(root->right, depth + 1);if (depth > 1) cout << ")";}
}void getInfixExp(TreeNode<char>* root) {dfs(root, 1);
}
判定順序存儲二叉樹是否為二叉搜索樹
題目描述
已知非空二叉樹 T 結點值均為正整數,采用順序存儲方式存儲,T 中不存在的結點在數組中用 -1 表示。請設計一個盡可能高效的算法,判定一棵采用這種方式存儲的二叉樹是否為二叉搜索樹。
解題代碼
bool dfs(vector<int>& T, int idx, int& lastVal) {if (idx - 1 >= T.size() || T[idx - 1] == -1) return true;if (!dfs(T, idx * 2, lastVal) || T[idx - 1] <= lastVal) return false;lastVal = T[idx - 1];return dfs(T, idx * 2 + 1, lastVal);
}bool isBST(vector<int>& T) {int lastVal = INT32_MIN;return dfs(T, 1, lastVal);
}
根據層序序列建立二叉樹
題目描述
設一棵二叉樹層序遍歷序列存儲于一個一維數組中,空結點用 INT32_MAX
表示,試編寫算法建立該二叉樹的二叉鏈表。
解題代碼
TreeNode* createTreeByOrder(vector<int>& order) {if (order.front() == INT32_MAX) return nullptr;queue<TreeNode*> q;int idx = 0;TreeNode* root = new TreeNode(order[idx++]);q.emplace(root);while (!q.empty()) {TreeNode* fNode = q.front();q.pop();if (fNode == nullptr) continue;if (idx < order.size()) {TreeNode* lChild = nullptr;if (order[idx] != INT32_MAX) {lChild = new TreeNode(order[idx]);}fNode->left = lChild;q.emplace(lChild);++idx;}if (idx < order.size()) {TreeNode* rChild = nullptr;if (order[idx] != INT32_MAX) {rChild = new TreeNode(order[idx]);}fNode->right = rChild;q.emplace(rChild);++idx;}}return root;
}