日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树的创建_大多数人都不会手写创建并遍历二叉树,一航这里帮你终结了

發布時間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树的创建_大多数人都不会手写创建并遍历二叉树,一航这里帮你终结了 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
創建二叉樹、遍歷二叉樹、二叉樹的最近公共祖先任何疑問、意見、建議請公眾號留言或聯系qq474356284先序、后序創建二叉樹先中后層序遍歷二叉樹二叉樹的最近公共祖先? ?

輸入格式:

創建二叉樹時的輸入:

????如序列:{1?2?-1?-1?3?-1?-1}表示1結點有2,3兩個孩子,2,3結點沒有孩子。

????如序列:{3 5 6 -1?-1?2?7?-1?-1?4?-1?-1?1?9?-1?-1?8?-1?-1}

其中-1表示結點為空。

需注意:已知先中、中后序可確定唯一二叉樹,先后序不能確定唯一二叉樹。(這里指的是遍歷后的序列,而不是這里輸入時的序列,因為輸入時的序列含有空節點,已經含有二叉樹的所有信息)

輸入樣例:

先序創建二叉樹:
1 2 -1 -1 3 -1 -1
3?5 6 -1 -1 2?7?-1 -1?4 -1 -1 1 9 -1 -1 8?-1 -1
后序創建二叉樹:
-1 -1?2 -1 -1?3 1
-1 -1?6?-1 -1?7 -1 -1?4 2 5?-1 -1 9 -1 -1?8 1 3

求兩節點最近的公共祖先:
2 3
5 1

輸出樣例:

先序:
1 2 3
中序:
2 1 3
后序:
2 3 1

先序:1 2 3中序:2 1 3后序:2 3 1

先序:
3 5 6 2 7?4 1?9 8中序:
6 5 7 2 4?3 9 1 8
后序:
6 7 4 2?5 9?8?1 3

最近公共祖先:
1
3

解決方法:

待補充。

2021校招金山云9.16筆試題最近公共祖先(須自己創建二叉樹)

(1)代碼實現:

#include #include #include #include #include #include #include #include using namespace std;//一航代碼//樹節點定義(此處與leetcode定義保持一致)struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x): val(x), left(NULL), right(NULL){}//初值列};//創建二叉樹//先中->√ 先后->× 中后->√class creat_tree {public: //先序創建一棵樹 void creatpre(TreeNode** root){ /*如序列:{1 2 -1 -1 3 -1 -1}表示1結點有2,3兩個孩子,2,3結點沒有孩子。 如序列:{3 5 6 -1 -1 2 7 -1 -1 4 -1 -1 1 9 -1 -1 8 -1 -1}*/ int val; cin >> val; if (val == -1) root = nullptr; else { *root = new TreeNode(val); creatpre(&((*root)->left)); creatpre(&((*root)->right)); } } //后序創建一棵樹 void creatpost(TreeNode** root, vector<int>& t, bool flag){ /*如序列:{-1 -1 2 -1 -1 3 1}表示1結點有2,3兩個孩子,2,3結點沒有孩子。 如序列:{-1 -1 6 -1 -1 7 -1 -1 4 2 5 -1 -1 9 -1 -1 8 1 3}*/ int val; char ch; if (flag) { //flag標記第一次獲取二叉樹序列 while (cin >> val) { t.push_back(val); if ((ch = getchar()) == '\n') break; } flag = false; } static int count = t.size(); val = t[--count]; if (val == -1) root = nullptr; else { *root = new TreeNode(val); creatpost(&((*root)->right), t, flag); creatpost(&((*root)->left), t, flag); } }};//先中后三種遞歸遍歷方式class traversal_rec {public: vector<int> ans; vector<int> preorder(TreeNode* root) { if (root == NULL) return ans; ans.push_back(root->val); preorder(root->left); preorder(root->right); return ans; } vector<int> inorder(TreeNode* root) { if (root == NULL) return ans; inorder(root->left); ans.push_back(root->val); inorder(root->right); return ans; } vector<int> posorder(TreeNode* root) { if (root == NULL) return ans; posorder(root->left); posorder(root->right); ans.push_back(root->val); return ans; }};//先中后三種迭代遍歷二叉樹參考:https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRgclass traversal_ite {public: vector<int> res; //保存結果 vector<int> preorder(TreeNode* root) { stack call; //調用棧 if (root != nullptr) call.push(root); //首先介入root節點 while (!call.empty()) { TreeNode* t = call.top(); call.pop(); //訪問過的節點彈出 if (t != nullptr) { if (t->right) call.push(t->right); //右節點先壓棧,最后處理 if (t->left) call.push(t->left); call.push(t); //當前節點重新壓棧(留著以后處理),因為先序遍歷所以最后壓棧 call.push(nullptr); //在當前節點之前加入一個空節點表示已經訪問過了 } else { //空節點表示之前已經訪問過了,現在需要處理除了遞歸之外的內容 res.push_back(call.top()->val); // call.top()是nullptr之前壓棧的一個節點,也就是上面call.push(t)中的那個t call.pop(); //處理完了,第二次彈出節點(徹底從棧中移除) } } return res; } vector<int> inorder(TreeNode* root) { stack call; if (root != nullptr) call.push(root); while (!call.empty()) { TreeNode* t = call.top(); call.pop(); if (t != nullptr) { if (t->right) call.push(t->right); call.push(t); //在左節點之前重新插入該節點,以便在左節點之后處理(訪問值) call.push(nullptr); //nullptr跟隨t插入,標識已經訪問過,還沒有被處理 if (t->left) call.push(t->left); } else { res.push_back(call.top()->val); call.pop(); } } return res; } vector<int> postorder(TreeNode* root) { stack call; if (root != nullptr) call.push(root); while (!call.empty()) { TreeNode* t = call.top(); call.pop(); if (t != nullptr) { call.push(t); //在右節點之前重新插入該節點,以便在最后處理(訪問值) call.push(nullptr); //nullptr跟隨t插入,標識已經訪問過,還沒有被處理 if (t->right) call.push(t->right); if (t->left) call.push(t->left); } else { res.push_back(call.top()->val); call.pop(); } } return res; }};//層序遍歷二叉樹class level_order {public: vector<vector<int>> levelOrder(TreeNode* root) { queue que; if (root != NULL) que.push(root); vector<vector<int>> result; while (!que.empty()) { int size = que.size(); vector<int> vec; for (int i = 0; i < size; i++) { // 這里一定要使用固定大小size,不要使用que.size(),因為que.size是不斷變化的 TreeNode* node = que.front(); que.pop(); vec.push_back(node->val); if (node->left) que.push(node->left); if (node->right) que.push(node->right); } result.push_back(vec); } return result; }};// p結點與q結點的最近公共祖先TreeNode* lowc(TreeNode* root, int p, int q){ if (root == nullptr) return 0; if (root->val == p || root->val == q) return root; TreeNode* rleft = lowc(root->left, p, q); TreeNode* rright = lowc(root->right, p, q); if (rleft != nullptr && rright != nullptr) return root; else if (rright != nullptr) return rright; else return rleft; return nullptr;}int main(){ creat_tree creat; TreeNode* root; //先序創建二叉樹 creat.creatpre(&root); //后序創建二叉樹 // vector tree; // creat.creatpost(&root, tree, true); traversal_rec rec; vector<int> res = rec.preorder(root); // vector res = rec.inorder(root); // vector res = rec.posorder(root); traversal_ite ite; // vector res = ite.preorder(root); // vector res = ite.inorder(root); // vector res = ite.postorder(root); for (int i = 0; i < (int)res.size(); i++) {//注意最后一個節點輸出后面有空格 cout << res[i] << " "; } cout << endl; // level_order level; //層序輸出 // vector> res = level.levelOrder(root); // for(int i = 0;i < (int)res.size();i++){ // for(int j = 0;j < (int)res[i].size();j++){ // cout << res[i][j] << " "; // } // } //求二叉樹結點p,q最近的公共祖先 int p, q; cin >> p >> q; TreeNode *t = lowc(root, p, q); cout << t->val << endl; return 0;}

總結

以上是生活随笔為你收集整理的二叉树的创建_大多数人都不会手写创建并遍历二叉树,一航这里帮你终结了的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。