数据结构的一些知识很久没碰了,忘得差不多了都,来回顾总结一下,本篇先写一下二叉树相关的一些操作。
二叉树定义
struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} };
二叉树的创建
通过输入先序二叉树序列创建二叉树,用'#'字符代表空节点。
//通过先序输入创建二叉树 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); }
还有一种层次遍历方式,从上往下逐层遍历,需要借助队列实现,每次将父结点出队,子结点进队即可。
//层次遍历 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; } };
二叉树序列化与反序列化
序列化就是指将二叉树转换成一个序列(比如字符串),反序列化就是将转换的序列还原成二叉树。
序列化
没啥好说的,按照先序遍历依次写入字符串。
//序列化二叉树(先序),结果保存在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索引来从字符串中读取当前结点对应字符。
//反序列化方法(先序) 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); } } };
来源:https://www.cnblogs.com/LiveForGame/p/12287600.html