二叉树学习小结(序列化和反序列化、二叉树遍历、二叉树镜像、二叉搜索树、二叉树子结构等)

【信息科学与工程学】【数据科学】数据科学领域 第六篇 算法设计 07 堆、栈、表、矩阵、集合、队列、数组、字符串、树、图、动态规划、结构体、元组的算法01 当前段必须包含所有字符的最后出现位置。1. 字符串分割成最多片段2. 基因序列功能域划分3. 文本段落划分4. 音频声道分离5. 图像色彩分区6. 社交网络社群划分7. 蛋白质结构域8. 音乐乐章分段9. 代码模块划分10. 章节划分特征:一次扫描,贪心确定边界。 阅读详情

二叉树

[cpp]  view plain  copy
  1. struct TreeNode {  
  2.     int val;  
  3.     struct TreeNode *left;  
  4.     struct TreeNode *right;  
  5.     TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
  6. };  

二叉树的序列化及反序列化

序列化二叉树

[cpp]  view plain  copy
  1. //==================================================  
  2. // 序列化二叉树  
  3. //==================================================  
  4. void serializeBTree(TreeNode* pRoot, ostream& out, char mark, char separator) {  
  5.     if(NULL == pRoot) {  
  6.         out << mark << separator;  
  7.         return;  
  8.     }  
  9.     out << pRoot->val << separator;  
  10.     serializeBTree(pRoot->left, out, mark, separator);  
  11.     serializeBTree(pRoot->right, out, mark, separator);  
  12. }  
  13. /* 序列化二叉树 
  14.  * pRoot:要序列化的二叉树 
  15.  * mark:叶子节点下的 NULL 指针标记符(默认为 #) 
  16.  * separator:分隔符(默认为空格) 
  17.  */  
  18. string Serialize(TreeNode *pRoot, char mark, char separator) {//【序列化二叉树】  
  19.     ostringstream os;  
  20.     if(NULL != pRoot) {  
  21.         serializeBTree(pRoot, os, mark, separator);  
  22.     }  
  23.     return os.str();  
  24. }  

反序列化二叉树

[cpp]  view plain  copy
  1. //==================================================  
  2. // 反序列化二叉树  
  3. //==================================================  
  4. // 使用流  
  5. bool readStream(istream& in, int& num, char mark, char separator) {  
  6.     if(' ' == separator) {// 空格分割的情况  
  7.         string str;  
  8.         in >> str;  
  9.         if("#" == str)  
  10.             return false;  
  11.         num = atoi(str.c_str());  
  12.         return true;  
  13.     } else {// 其他字符分割的情况  
  14.         char ch;  
  15.         string s = "";  
  16.         in >> ch;  
  17.         while(ch != separator) {  
  18.             s += ch;  
  19.             in >> ch;  
  20.         }  
  21.         if(s[0] != mark) {  
  22.             num = atoi(s.c_str());  
  23.             return true;  
  24.         }  
  25.         return false;  
  26.     }  
  27. }  
  28. void deserializeBTree(TreeNode* &pRoot, istream& in, char mark, char separator) {// 使用流  
  29.     int num;  
  30.     if(readStream(in, num, mark, separator)) {  
  31.         pRoot = new TreeNode(num);  
  32.         deserializeBTree(pRoot->left, in, mark, separator);  
  33.         deserializeBTree(pRoot->right, in, mark, separator);  
  34.     }  
  35. }  
  36. // 使用 string  
  37. bool readString(string& str, int& num, char mark, char separator) {  
  38.     string::size_type index = str.find_first_of(separator);  
  39.     if(string::npos != index) {  
  40.         string s = str.substr(0, index);  
  41.         str = str.substr(index+1);  
  42.         if(s[0] != mark) {  
  43.             num = atoi(s.c_str());  
  44.             return true;  
  45.         }  
  46.     }  
  47.     return false;  
  48. }  
  49. void deserializeBTree(TreeNode* &pRoot, string& str, char mark, char separator) {// 使用 string  
  50.     int num;  
  51.     if(readString(str, num, mark, separator)) {  
  52.         pRoot = new TreeNode(num);  
  53.         deserializeBTree(pRoot->left, str, mark, separator);  
  54.         deserializeBTree(pRoot->right, str, mark, separator);  
  55.     }  
  56. }  
  57. /* 反序列化二叉树 
  58.  * str:string 型的序列 
  59.  * mark:叶子节点下的 NULL 指针标记符(默认为 #) 
  60.  * separator:分隔符(默认为空格) 
  61.  */  
  62. TreeNode* Deserialize(string sequence, char mark, char separator){//【反序列化二叉树】  
  63.     TreeNode* pRoot = NULL;  
  64.   
  65. //    istringstream in(sequence);  
  66. //    deserializeBTree(pRoot, in, mark, separator);// 使用流  
  67.   
  68.     deserializeBTree(pRoot, sequence, mark, separator);// 使用 string  
  69.   
  70.     return pRoot;  
  71. }  

二叉树的遍历(递归)

[cpp]  view plain  copy
  1. //==================================  
  2. //        二叉树遍历(递归)  
  3. //==================================  
  4. void PreorderTravel(TreeNode *pRoot) {// 【先序遍历(递归)】  
  5.     if(pRoot) {  
  6.         cout << pRoot->val << " ";  
  7.         PreorderTravel(pRoot->left);  
  8.         PreorderTravel(pRoot->right);  
  9.     }  
  10. }  
  11.   
  12. void InorderTravel(TreeNode *pRoot) {// 【中序遍历(递归)】  
  13.     if(pRoot) {  
  14.         InorderTravel(pRoot->left);  
  15.         cout << pRoot->val << " ";  
  16.         InorderTravel(pRoot->right);  
  17.     }  
  18. }  
  19.   
  20. void PostorderTravel(TreeNode *pRoot) {// 【后序遍历(递归)】  
  21.     if(pRoot) {  
  22.         PostorderTravel(pRoot->left);  
  23.         PostorderTravel(pRoot->right);  
  24.         cout << pRoot->val << " ";  
  25.     }  
  26. }  

二叉树的遍历(非递归)

[cpp]  view plain  copy
  1. //==================================  
  2. //        二叉树遍历(非递归)  
  3. //==================================  
  4. void PreorderNonRecursive(TreeNode *pRoot) { // 【前序遍历(非递归)】  
  5.     stack<TreeNode*> s;  
  6.     TreeNode *p = pRoot;  
  7.     while(p != NULL || !s.empty()) {  
  8.         while(p != NULL) {  
  9.             cout << p->val << " ";// 根  
  10.             s.push(p);  
  11.             p = p->left;// 左  
  12.         }  
  13.         if(!s.empty()) {  
  14.             p = s.top();  
  15.             s.pop();  
  16.             p = p->right;// 右  
  17.         }  
  18.     }  
  19. }  
  20.   
  21. void InorderNonRecursive(TreeNode *pRoot) { // 【中序遍历(非递归)】  
  22.     stack<TreeNode*> s;  
  23.     TreeNode *p = pRoot;  
  24.     while(p != NULL || !s.empty()) {  
  25.         while(p != NULL) {  
  26.             s.push(p);  
  27.             p = p->left;// 左  
  28.         }  
  29.         if(!s.empty()) {  
  30.             p = s.top();  
  31.             cout << p->val << " ";// 根  
  32.             s.pop();  
  33.             p = p->right;// 右  
  34.         }  
  35.     }  
  36. }  
  37. /* 后序遍历:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点 p,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它; 
  38.  * 或者 p 存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。 
  39.  * 若非上述两种情况,则将 p 的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。*/  
  40. void PostorderNonRecursive(TreeNode *pRoot) { // 【后序遍历(非递归)】  
  41.     stack<TreeNode*> s;  
  42.     TreeNode *cur;// 当前结点  
  43.     TreeNode *pre = NULL;// 前一次访问的结点  
  44.     s.push(pRoot);  
  45.     while(!s.empty()) {  
  46.         cur = s.top();  
  47.         if((cur->left == NULL && cur->right == NULL) || // 如果当前结点没有孩子结点  
  48.                 (pre != NULL && (pre == cur->left || pre == cur->right))// 如果有孩子,因为孩子们是先入栈的,只要有一个孩子访问了,肯定是孩子们都被访问了(因为他们比当前结点先入栈的)  
  49.           ) {  
  50.             cout << cur->val << " ";  
  51.             s.pop();  
  52.             pre = cur;  
  53.         } else {  
  54.             if(cur->right != NULL)// 右孩子先入栈,这样,每次取栈顶元素的时候,左孩子在右孩子前面被访问  
  55.                 s.push(cur->right);  
  56.             if(cur->left != NULL)  
  57.                 s.push(cur->left);  
  58.         }  
  59.     }  
  60. }  

按层打印二叉树

从上往下打印二叉树(层序遍历不分行)

[cpp]  view plain  copy
  1. vector<int> TravelFromTopToBottom(TreeNode *pRoot) {// 【从上往下打印二叉树】  
  2.     vector<int> result;  
  3.     if(NULL == pRoot) return result;  
  4.     queue<TreeNode*> myQueue;  
  5.     myQueue.push(pRoot);  
  6.     while(!myQueue.empty()) {  
  7.         TreeNode *p = myQueue.front();  
  8.         result.push_back(p->val);  
  9.         myQueue.pop();  
  10.         if(p->left)  
  11.             myQueue.push(p->left);  
  12.         if(p->right)  
  13.             myQueue.push(p->right);  
  14.     }  
  15.     return result;  
  16. }  

把二叉树打印成多行(层序遍历分行)

[cpp]  view plain  copy
  1. vector<vector<int> > LevelTravel(TreeNode* pRoot) { // 【把二叉树打印成多行】  
  2.     vector<vector<int> > result;  
  3.     if(pRoot != NULL) {  
  4.         queue<TreeNode*> q;  
  5.         q.push(pRoot);  
  6.         int levelWith = 0;  
  7.         int n = 1;  
  8.         vector<int> v;  
  9.         while(!q.empty()) {  
  10.             TreeNode* p = q.front();  
  11.             v.push_back(p->val);  
  12.             if(p->left) {  
  13.                 q.push(p->left);  
  14.                 ++levelWith;  
  15.             }  
  16.             if(p->right) {  
  17.                 q.push(p->right);  
  18.                 ++levelWith;  
  19.             }  
  20.             q.pop();  
  21.             --n;  
  22.             if(0 == n) {  
  23.                 result.push_back(v);  
  24.                 v.resize(0);  
  25.                 n = levelWith;  
  26.                 levelWith = 0;  
  27.             }  
  28.         }  
  29.     }  
  30.     return result;  
  31. }  

按之字形顺序打印二叉树

[cpp]  view plain  copy
  1. vector<vector<int> > ZigzagTravel(TreeNode* pRoot) {// 【按之字形顺序打印二叉树】  
  2.     vector<vector<int> > result;  
  3.     if(NULL == pRoot) return result;  
  4.     stack<TreeNode*> s1/*从右到左压入*/, s2/*从左到右压入*/;  
  5.     s1.push(pRoot);  
  6.     vector<int> vec;  
  7.     while(!s1.empty() || !s2.empty()) {  
  8.         while(!s1.empty()) {  
  9.             TreeNode* node = s1.top();  
  10.             vec.push_back(node->val);  
  11.             if(node->left)  
  12.                 s2.push(node->left);  
  13.             if(node->right)  
  14.                 s2.push(node->right);  
  15.             s1.pop();  
  16.         }  
  17.         result.push_back(vec);  
  18.         vec.resize(0);  
  19.         while(!s2.empty()) {  
  20.             TreeNode* node = s2.top();  
  21.             vec.push_back(node->val);  
  22.             if(node->right)  
  23.                 s1.push(node->right);  
  24.             if(node->left)  
  25.                 s1.push(node->left);  
  26.             s2.pop();  
  27.         }  
  28.         result.push_back(vec);  
  29.         vec.resize(0);  
  30.     }  
  31.     return result;  
  32. }  

重建二叉树

根据前序和中序重建二叉树

[cpp]  view plain  copy
  1. TreeNode* constrcutBT(const vector<int>& pre, vector<int>::size_type preLow, vector<int>::size_type preHigh,  
  2.                       const vector<int>& in, vector<int>::size_type inLow, vector<int>::size_type inHigh) {  
  3.     // 前序的第一个是根  
  4.     int rootValue = pre[preLow];  
  5.     TreeNode* tree = new TreeNode(rootValue);  
  6.   
  7.     if(0 == preHigh-preLow && 0 == inHigh-inLow && pre[preLow] == in[inLow])  
  8.         return tree;  
  9.   
  10.     // 在中序里面找到这个根的位置  
  11.     vector<int>::size_type i = inLow;  
  12.     for(; i != inHigh; i++) {  
  13.         if(rootValue == in[i])  
  14.             break;  
  15.     }  
  16.   
  17.     if(i > inLow) {// 重建左子树  
  18.         vector<int>::size_type in_L_Low = inLow, in_L_High = i - 1;// 左子树的中序起始点  
  19.         vector<int>::size_type pre_L_Low = preLow + 1, pre_L_High = preLow + (i - inLow);// 左子树的前序起始点  
  20.         tree->left = constrcutBT(pre, pre_L_Low, pre_L_High, in, in_L_Low, in_L_High);  
  21.     }  
  22.     if(i < inHigh) {// 重建右子树  
  23.         vector<int>::size_type in_R_Low = i + 1, in_R_High = inHigh;// 右子树的中序起始点  
  24.         vector<int>::size_type pre_R_Low = preLow + (i - inLow) + 1, pre_R_High = preHigh;// 右子树的前序起始点  
  25.         tree->right = constrcutBT(pre, pre_R_Low, pre_R_High, in, in_R_Low, in_R_High);  
  26.     }  
  27.     return tree;  
  28. }  
  29. struct TreeNode* ReConstructBinaryTree(vector<int> pre, vector<int> in) {// 【根据前序和中序重建二叉树】  
  30.     if(pre.empty() || in.empty() || pre.size() != in.size())  
  31.         return NULL;  
  32.     return constrcutBT(pre, 0, pre.size()-1, in, 0, in.size()-1);  
  33. }  

判断二叉树是否是对称二叉树

[cpp]  view plain  copy
  1. bool isSymm(TreeNode* pRoot1, TreeNode* pRoot2) {  
  2.     if(NULL == pRoot1 && NULL == pRoot2) return true;  
  3.     if(NULL == pRoot1 || NULL == pRoot2) return false;  
  4.     if(pRoot1->val != pRoot2->val) return false;  
  5.     return (isSymm(pRoot1->left, pRoot2->right) && isSymm(pRoot1->right, pRoot2->left));  
  6. }  
  7. bool IsSymmetrical(TreeNode* pRoot) {// 【对称二叉树】  
  8.     return isSymm(pRoot, pRoot);  
  9. }  

二叉树的镜像(对换左右子树)

[cpp]  view plain  copy
  1. void Mirror(TreeNode *pRoot) {// 【二叉树的镜像(对换左右子树)】  
  2.     if(pRoot != NULL) {  
  3.         TreeNode *p = pRoot->left;  
  4.         pRoot->left = pRoot->right;  
  5.         pRoot->right = p;  
  6.         Mirror(pRoot->left);  
  7.         Mirror(pRoot->right);  
  8.     }  
  9. }  

判断树的子结构

[cpp]  view plain  copy
  1. bool hasST(TreeNode *pRoot1, TreeNode *pRoot2) {// 判断树1中以此节点为根节点的子树是不是包含数2一样的结构  
  2.     if(NULL == pRoot2) return true;// 递归终止条件  
  3.     if(NULL == pRoot1) return false;  
  4.     if(pRoot1->val != pRoot2->val) return false;  
  5.     return (hasST(pRoot1->left, pRoot2->left) && hasST(pRoot1->right, pRoot2->right));  
  6. }  
  7. bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {// 【判断树 pRoot2 是不是树 pRoot1 的子结构】  
  8.     bool flag = false;  
  9.     if(pRoot1 != NULL && pRoot2 != NULL) {  
  10.         if(pRoot1->val == pRoot2->val)// 在树1中找到和树2的根节点的值一样的节点  
  11.             flag = hasST(pRoot1, pRoot2);// 判断树1中以此节点为根节点的子树是不是包含数2一样的结构  
  12.         if(!flag)  
  13.             flag = HasSubtree(pRoot1->left, pRoot2);// 在左子树中查找  
  14.         if(!flag)  
  15.             flag = HasSubtree(pRoot1->right, pRoot2);// 在右子树中查找  
  16.     }  
  17.     return flag;  
  18. }  

判断二叉树是否是平衡二叉树

[cpp]  view plain  copy
  1. bool isBalanced(TreeNode* pRoot, int& depth) {  
  2.     if(!pRoot) {  
  3.         depth = 0;  
  4.         return true;  
  5.     }  
  6.     int leftDepth, rightDepth;  
  7.     // 如果左右子树是平衡的,则计算当前节点作为根节点的树是否是平衡的  
  8.     if(isBalanced(pRoot->left, leftDepth) && isBalanced(pRoot->right, rightDepth)) {  
  9.         int d = abs(leftDepth - rightDepth);  
  10.         if(d <= 1) {  
  11.             depth = leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;  
  12.             return true;  
  13.         }  
  14.     }  
  15.     return false;  
  16. }  
  17. bool IsBalanced(TreeNode* pRoot) {// 【判断二叉树是否是平衡二叉树】  
  18. //    // 方案一  
  19. //    if(!pRoot)  
  20. //        return true;  
  21. //    int leftDepth = TreeDepth(pRoot->left);// 计算左子树深度  
  22. //    int rightDepth = TreeDepth(pRoot->right);// 计算右子树深度  
  23. //    int d = abs(leftDepth - rightDepth);// 左右子树深度差  
  24. //    if(d > 1)// 如果深度差超过 1 则不是平衡二叉树  
  25. //        return false;  
  26. //    return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);  
  27.   
  28.     // 方案二(方案一中一个结点会被重复遍历多次,效率不高。这里方案二采用后序遍历的方式,每个节点只访问一次)  
  29.     int depth;  
  30.     return isBalanced(pRoot, depth);  
  31. }  

二叉树的深度

[cpp]  view plain  copy
  1. //void getTreeDepth(TreeNode* p, int& depth, int& maxDepth) {  
  2. //    if(p) {  
  3. //        depth++;  
  4. //        if(!p->left && !p->right) {// 如果到了叶子节点,则更新深度值  
  5. //            if(depth > maxDepth)  
  6. //                maxDepth = depth;  
  7. //        }  
  8. //        else {  
  9. //            if(p->left) {  
  10. //                getTreeDepth(p->left, depth, maxDepth);  
  11. //                depth--;  
  12. //            }  
  13. //            if(p->right)  
  14. //                getTreeDepth(p->right, depth, maxDepth);  
  15. //        }  
  16. //    }  
  17. //}  
  18. //int TreeDepth(TreeNode* pRoot) {//【二叉树的深度】方案一  
  19. //    int depth = 0, maxDepth = 0;  
  20. //    getTreeDepth(pRoot, depth, maxDepth);  
  21. //    return maxDepth;  
  22. //}  
  23. int TreeDepth(TreeNode* pRoot) {//【二叉树的深度】方案二  
  24.     if(!pRoot) return 0;  
  25.     int leftDepth = TreeDepth(pRoot->left);// 计算左子树深度  
  26.     int rightDepth = TreeDepth(pRoot->right);// 计算右子树深度  
  27.     return (leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1);// 树的深度为较大者深度 + 1  
  28. }  

二叉树中和为某一值的路径

[cpp]  view plain  copy
  1. void findPath(TreeNode* root, int& curSum, const int& expectNumber, vector<int>& path, vector<vector<int> >& paths) {  
  2.     if(root) {  
  3.         curSum += root->val;  
  4.         path.push_back(root->val);  
  5.         if(NULL == root->left && NULL == root->right && curSum == expectNumber)  
  6.             paths.push_back(path);  
  7.         if(root->left)  
  8.             findPath(root->left, curSum, expectNumber, path, paths);  
  9.         if(root->right)  
  10.             findPath(root->right, curSum, expectNumber, path, paths);  
  11.         curSum -= root->val;  
  12.         path.pop_back();  
  13.     }  
  14. }  
  15. vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {// 【二叉树中和为某一值的路径】  
  16.     vector<vector<int> > paths;  
  17.     if(NULL == root) return paths;  
  18.     int curSum = 0;  
  19.     vector<int> path;  
  20.     findPath(root, curSum, expectNumber, path, paths);  
  21.     return paths;  
  22. }  

二叉搜索树

判断一个序列是不是二叉搜索树的后序遍历序列

[cpp]  view plain  copy
  1. bool VerifySquenceOfBST(vector<int> sequence) {// 【判断一个序列是不是二叉搜索树的后序遍历序列】  
  2.     if(sequence.empty()) return false;  
  3.     int rootValue = sequence[sequence.size()-1];// 根节点  
  4.     vector<int>::size_type length = 0, i = 0;  
  5.     for(; i < sequence.size()-1; i++)// 寻找根节点左右子树分割点  
  6.         if(sequence[i] > rootValue)  
  7.             break;  
  8.     length = i;// 左子树节点数  
  9.     for(++i; i < sequence.size()-1; i++)// 判断右子树节点中,是否有小于根节点值的  
  10.         if(sequence[i] < rootValue)  
  11.             return false;  
  12.     bool L_flag = true, R_flag = true;  
  13.     if(length > 0) {// 递归判断左子树  
  14.         vector<int> vecL(sequence.begin(), sequence.begin()+length);  
  15.         L_flag = VerifySquenceOfBST(vecL);  
  16.     }  
  17.     if(length < sequence.size()-1) {// 递归判断右子树  
  18.         vector<int> vecR(sequence.begin()+length, sequence.end()-1);  
  19.         R_flag = VerifySquenceOfBST(vecR);  
  20.     }  
  21.     return (L_flag && R_flag);  
  22. }  

二叉搜索树转为双向链表

[cpp]  view plain  copy
  1. void convertTree2List(TreeNode* p, TreeNode* &pList) {  
  2.     if(p) {  
  3.         if(p->left)  
  4.             convertTree2List(p->left, pList);// 转换左子树  
  5.   
  6.         p->left = pList;// 将此根节点左边指向双向链表的最右边  
  7.         if(pList)  
  8.             pList->right = p;// 双向链表的最右边的节点指向此根节点  
  9.         pList = p;// 更新 pList 指向双向链表的最右边  
  10.   
  11.         if(p->right)  
  12.             convertTree2List(p->right, pList);// 转换右子树  
  13.     }  
  14. }  
  15. TreeNode* Convert(TreeNode* pRootOfTree) {// 【二叉搜索树转为双向链表】  
  16.     if(pRootOfTree) return NULL;  
  17.     TreeNode *pList/*指向双向链表最右边那个节点*/ = NULL, *pListHead/*双向链表*/ = NULL;  
  18.     convertTree2List(pRootOfTree, pList);  
  19.     pListHead = pList;  
  20.     while(pListHead && pListHead->left)// 因为 pList 指向的是双向链表的最右边,所以反向遍历到最左边得到表头  
  21.         pListHead = pListHead->left;  
  22.     return pListHead;  
  23. }  

二叉搜索树的第 k 个结点

给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 3 2 # # 4 # # 7 6 # # 8 # #,按结点数值大小顺序第三个结点的值为 4 
[cpp]  view plain  copy
  1. bool FindKthOfBST(TreeNode* pRoot, int& k, int& val) {//【查找二叉搜索树的第 k 小的结点,若找到返回 true,并用 val 存放这个结点的值】  
  2.     // 用中序遍历即可从小到大访问二叉搜索树的结点  
  3.   
  4.     bool isFind = false;  
  5.     if(pRoot != NULL) {  
  6.         // 左  
  7.         isFind = FindKthOfBST(pRoot->left, k, val);  
  8.         // 根  
  9.         k--;  
  10.         if(0 == k) {  
  11.             val = pRoot->val;  
  12.             isFind = true;  
  13.         }  
  14.         // 右  
  15.         if(!isFind)  
  16.             isFind = FindKthOfBST(pRoot->right, k, val);  
  17.     }  
  18.     return isFind;  
  19. }  
Python算法——树的序列化与反序列化 树的序列化与反序列化是指将树结构转换为字符串表示(序列化),以及将字符串表示还原为原始树结构(反序列化)。在本文中,我们将深入讨论如何实现树的序列化与反序列化算法,提供Python代码实现,并详细说明算法的原理和步骤。这表示通过序列化与反序列化算法,我们能够将二叉树转换为字符串表示,并成功还原为原始树结构。树的反序列化需要根据序列化字符串的规律,逐个还原树的节点。对于前序遍历序列化,我们可以通过递归的方式还原;我们可以使用前序遍历或层序遍历的方式将树的节点逐个转换为字符串,并使用特殊符号表示空节点。 阅读详情

相关推荐

syn-serde:用于序列化和反序列化Syn语法树的库

同步 用于序列化和反序列化语法树的库。 用法 将此添加到您的Cargo.toml : [ dependencies ] syn-serde = " 0.2 " 编译器支持:需要rustc 1.31+ 例子 [ dependencies ] syn-serde = { version = " 0.2 " , features = [ " json " ] } syn = { version = " 1 " , features = [ " full " ] } use syn_serde :: json; let syn_file: syn :: File = syn :: parse_quote! { fn main () { println! ( "Hello, world!" ); } }; println! ( "{}" , json :: t

二叉树的序列化和反序列化

设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。 样例 样例 1: 输入:{3,9,20,#,#,15,7} 输出:{3,9,20,#,#,15,7} 解释: 二叉树 {3,9,20...

weixin_41791402的博客 261

BitLocker磁盘锁定解决方法

摘要:本文介绍了BitLocker加密磁盘被锁的两种情况及解决方法。对于系统盘锁定,建议在微软账户中查找48位恢复密钥;数据盘锁定可尝试密码或恢复密钥解锁。若密钥丢失,可通过IT支持或数据恢复服务尝试解决。预防措施包括妥善备份密钥到微软账户和离线位置,避免随意更改系统硬件配置。BitLocker安全性高,恢复密钥是解锁关键,提醒用户务必做好备份以防数据丢失。(148字)

yueke06442300的专栏 2674

算法小抄学习笔记 — 3.二叉树序列化与反序列化

1 二叉树的序列化与反序列化 二叉树的序列化是指将二叉树转换为唯一标识的字符串,反序列化是指将字符串转换为相应的二叉树。 二叉树可以使用先序、中序、后序和层次遍历进行序列化,可以使用先序、后序和层次遍历进行反序列化。(中序遍历不可以反序列化) 如何判断两个二叉树相等?可能想法就是遍历二叉树,依次比较节点是否相等,这是没有问题的。但是如何判断子树中是否相等呢?可能就需要将所有子树序列化,加入一个map集合,从而判断所有相等的子树。652 寻找重复的子树,就使用了这个思想,将在下一笔记中总结此题。

Cigar 359

C++控制台实现简单的注册登录

C++控制台实现简单的注册登录 #include<iostream> #include<string> #include <vector> #include <conio.h> void Display();//调用display显示switch()界面 void Register();//注册 void Enter();//登录 using nam...

乔路非 2万+

K-近邻算法: k-nearest neighbor classification (kNN) 详细介绍

@创建于:2020.04.09 @修改于:2020.04.09,2024.06.22 文章目录1、kNN介绍2、k近邻法的三要素详解2.1 距离度量2.2 k值的选择2.3 分类决策规则3、k近邻法的实现:kd树4、Python实现过程5、优缺点6、常见问题 1、kNN介绍 kNN是一个基本而简单的分类算法,作为监督学习,那么KNN模型需要的是有标签的训练数据,对于新样本的类别由与新样本距离最近的k个训练样本点按照分类...

chenhepg的博客 9万+

学习笔记—二叉树的序列化和反序列化

二叉树的序列化,如下所示二叉树的前序序列化为:1_2_4_#_#_5_#_#_3_6_#_#_7_#_#,其中#可以用于表示NULL 一、实现前序序列化代码: 代码很简单,和前序遍历差不多,最后返回一个string类型的字符串 //先序遍历序列化 string serialBypre(TreeNode* root) { if (root == NULL) return "#_";...

Pichairen 584

机器人控制仿真软件:MATLAB Simulink Control System Toolbox_(1).MATLAB基础知识

MATLAB(Matrix Laboratory)是由MathWorks公司开发的一种高性能数值计算和可视化软件。它广泛应用于科学计算、工程设计、信号处理、控制系统设计、图像处理等领域。强大的矩阵运算能力:MATLAB的核心是矩阵运算,能够高效处理大规模的数值数据。丰富的工具箱:MATLAB提供了大量的工具箱,如Control System Toolbox、Simulink、Signal Processing Toolbox等,这些工具箱覆盖了多个应用领域。易于使用的图形界面。

kkchenjj的博客 904

二叉树的序列和反序列化总结 python C++

文章目录前言二叉树的读取和输出中序遍历pythonC++层序遍历pythonC++链表的读取和输出链表翻转pythonC++常规数据的读取和输出pythonC++ 前言 实际面试中不会像力扣一样给你定义好二叉树或者是链表的节点类,我们需要自己将输入数据转换为题目需要的数据结构,本文记录一些常用的数据读取模板和技巧,记住之后在面试手撕代码时可以直接使用。 二叉树和数组的转换可以通过层序遍历实现,力扣上也有原题,熟悉的话就可以不用往下看了。 二叉树的读取和输出 中序遍历 python C++ 层序遍历 py.

dhj_tsukuba的博客 419

基于STM32设计的自动追光系统(项目资料ID:2)

基于STM32设计的自动追光系统主要由光敏采集电路、单片机核心板电路和步进电机控制电路构成。通过光敏电阻采集环境光强信息,经 STM32 单片机处理后,控制步进电机转动,实现对光源的自动追踪。该系统具有响应速度快、追踪精度较高等优点,可应用于太阳能发电、智能照明等领域,为相关场景提供高效的光资源利用方案。

以培养嵌入式工程师为己任 1万+

通信原理 | 随机数仿真 | 均匀、正态、双高斯、瑞利、莱斯、对数正态、nakagami、Suzuki分布的随机数仿真(matlab)

信道建模在通信系统设计和分析中扮演着至关重要的角色。它指的是使用数学和物理模型来描述和模拟无线或有线通信路径中的信号传播特性。

若北辰 1984

7. 树的序列化与反序列化( 二叉树 和 N叉树 )

string serialize(TreeNode* root) { string str = (root == NULL) ? "NULL/" : ""; if (root) { queue<TreeNode*> queue; queue.emplace(root); while (!queue.empty()) { int size = queue.size(); ...

没戴面具的小丑 1424

结构优化软件:OptiStruct_(11).拓扑优化

在OptiStruct中,设计空间可以通过定义设计区域来实现。设计区域是结构中可以进行材料变化的部分。几何区域:通过几何选择工具选择特定的区域。网格区域:通过网格选择工具选择特定的单元。假设我们有一个简单的梁结构模型,网格文件为beam.fem。我们希望在梁的中部进行拓扑优化,以减轻重量并保持刚度。

kkchenjj的博客 1367

二叉树c语言面试题,二叉树常见面试题小结

这篇文章是二叉树系列的终结篇,总结了一下二叉树常见的手撕面试题,题目多来源于剑指offer,考察的也多数基于对二叉树前中后序遍历的理解,下面具体看题目:public class TreeNode {int val;TreeNode left = null;TreeNode right = null;TreeNode parent = null;public TreeNode(int val) {t...

weixin_32272937的博客 491

android studio 2022打开了v1 签名但是生成的apk没有v1签名问题

我使用了Android Studio Flamingo | 2022.2.1 Patch 2版本的IDE编译了一个apk,但是apksigner查看apk的签名信息时,发现只有v2签名,没有v1签名。试着改小一下minSdkVersion 为23重新编译apk,再检测一下签名版本v1居然打开了!参考网上搜索到的方法,手动在build.gradle里面添加。但是编译出来的apk还是只有v2的签名。里面提到了v1签名还和。

hedalei的博客 466

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

剑指offer刷题记录--树

剑指offer刷题记录--树

qq_37746927的博客 1763

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

剑指offer笔记

文章目录01赋值运算符函数02单例模式03找一维数组04二维数组查找05替换字符串的空格06从尾开始输出单向链表07前序和中序构建二叉树08找出中序遍历的下一个节点09两个栈实现队列09队列如何实现栈10斐波那契数列11partition函数11快速排序11数字限定在较小范围内的0(n)方法排序11旋转数组的最小数字12矩阵中的路径13机器人的运动范围14动态规划14贪婪算法14剪绳子15.位运算...

Junekiler的博客 751

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

算法之树的序列化与反序列化

树的序列化和反序列化

weixin_43938846的博客 942

树的序列化、反序列化【前序、后序、层序】及常见树的题目

树的序列化、反序列化【前序、后序、层序】及常见树的题目

weixin_45565886的博客 964

序列化和反序列化二叉树 -----前序,中序,后序,层序

序列化(Serialization)是将对象转化为字节序列的过程,方便数据在网络传输和存储过程中的传递。在序列化过程中,对象的状态信息被转换为可以存储或传输的格式(如字节数组、XML、JSON等),以便在需要时能够将其反序列化为原始对象。序列化可以用于在不同的系统之间传输对象,或者将对象存储到磁盘上等。反序列化(Deserialization)则是将序列化后的字节流还原成对象的过程,即恢复原始的对象状态信息。

qq_64580912的博客 2293

算法61-树的序列化与反序列化

算法

weixin_41479678的博客 698

二叉树的序列化与反序列化

二叉树的序列化与反序列化

明朗晨光的专栏 2348

树的序列化和反序列化

树的序列化化

qq_57589085的博客 217

树的序列化与反序列化及应用

我们知道,先序和中序或者后序与中序都可以唯一确定一棵树,但是先序和后序不行。 今有两个需求:判断两棵树是否元素相等或是否元素对称。 方法1:先序和中序或者中序和后序可以唯一确定一棵树,那么我们把他们遍历生成的特征序列对比即可判断。 判相等:用递归函数,参数是两棵树的跟节点,两个节点采取任意一种遍历方式,以先序为例,return common(root1-&gt;left,root2-&gt;...

The Shawshank Redemption 2316
上一篇: 链表相关算法小结(判断环、复制、逆序等)
下一篇: 计算机网络学习小结
Solid7
博客等级 码龄11年 2粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值