數據結構的一些知識好久沒碰了,忘得差很少了都,來回顧總結一下,本篇先寫一下二叉樹相關的一些操做。node
struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} };
經過輸入先序二叉樹序列建立二叉樹,用'#'字符表明空節點。c++
//經過先序輸入建立二叉樹 TreeNode* CreateTreeByInput() { char ch; std::cin >> ch; if (ch == '#') return NULL;//輸入#表示建立結束 TreeNode* root = new TreeNode(ch); root->left = CreateTreeByInput(); root->right = CreateTreeByInput(); return root; }
先序、中序、後序三種基本遍歷方式。數據結構
//先序遍歷 void PreOrder(TreeNode* root) { if (root == NULL)return; std::cout << (char)root->val << ' '; PreOrder(root->left); PreOrder(root->right); } //中序遍歷 void InOrder(TreeNode* root) { if (root == NULL)return; PreOrder(root->left); std::cout << (char)root->val << ' '; PreOrder(root->right); } //後序遍歷 void PostOrder(TreeNode* root) { if (root == NULL)return; std::cout << (char)root->val << ' '; PreOrder(root->left); PreOrder(root->right); }
還有一種層次遍歷方式,從上往下逐層遍歷,須要藉助隊列實現,每次將父結點出隊,子結點進隊便可。code
//層次遍歷 void levelOrder(TreeNode* root) { if (root == NULL)return; queue<TreeNode*> q; q.push(root); while (!q.empty()) { TreeNode* now = q.front(); cout << (char)now->val << ' '; if (now->left != NULL)q.push(now->left); if (now->right != NULL)q.push(now->right); q.pop(); } }
LeetCode上一道題目:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
要求獲得自底向上的層次遍歷序列,只須要先按層次遍歷獲得序列,而後用頭插法插入最終集合便可。索引
class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int>> result; if(root==NULL)return result; queue<TreeNode*> q; q.push(root); while(!q.empty()) { vector<int> level; int cnt=q.size(); for(int i=0;i<cnt;i++) { TreeNode* node=q.front(); q.pop(); level.push_back(node->val); if(node->left!=NULL)q.push(node->left); if(node->right!=NULL)q.push(node->right); } result.insert(result.begin(),level); } return result; } };
序列化就是指將二叉樹轉換成一個序列(好比字符串),反序列化就是將轉換的序列還原成二叉樹。隊列
沒啥好說的,按照先序遍歷依次寫入字符串。ci
//序列化二叉樹(先序),結果保存在str中 void Serialize(TreeNode* root, std::string& str) { if (root == NULL) { str += "#"; return; } str += (char)root->val; Serialize(root->left, str); Serialize(root->right, str); }
反序列化就是按照先序遍歷建立的同時,用index索引來從字符串中讀取當前結點對應字符。leetcode
//反序列化方法(先序) TreeNode* Deserialize(const std::string str, int& index) { if (str == "" && index >= str.size())return NULL; if (str[index] == '#') { index++; return NULL; } TreeNode* root = new TreeNode(str[index++]); root->left = Deserialize(str, index); root->right = Deserialize(str, index); return root; } //調用反序列化 string str = "akjl#####"; int index = 0; TreeNode* root=Deserialize(str, index);
//二叉樹最大深度 int MaxDepth(TreeNode* root) { if (root == NULL)return 0; return max(MaxDepth(root->left), MaxDepth(root->right)) + 1; }
題目:https://leetcode-cn.com/problems/binary-tree-paths/
深搜完事,碰到葉子結點就說明找到一條路徑,加入結果集合,不然就繼續搜。字符串
class Solution { public: vector<string> binaryTreePaths(TreeNode* root) { vector<string> res; dfs(root,"",res); return res; } void dfs(TreeNode* root,string str,vector<string> &res) { if(root!=NULL) { str+=to_string(root->val); if(root->left==NULL&&root->right==NULL) { res.push_back(str);return; } dfs(root->left,str+"->",res); dfs(root->right,str+"->",res); } } };