[zz]编程之美-重建二叉树扩展问题1 2
2012-08-12 21:35
363 查看
zz http://blog.csdn.net/vividonly/article/details/6688327
编程之美3.9:重建二叉树
扩展问题1:如果前序和中序遍历的字母有重复的,那么怎么构造所有可能的解呢?
扩展问题2:如何判断给定的前序遍历和中序遍历的结果是合理的?
思路:
问题1:搜索所有可能的情况,并调用扩展问题2的解决方案,判断此情况是否合理(剪枝操作),如果合法,则构造解
问题2:递归判断左右子树是否合理,递归的返回条件是到达叶子节点。
代码及测试情况如下:
编程之美3.9:重建二叉树
扩展问题1:如果前序和中序遍历的字母有重复的,那么怎么构造所有可能的解呢?
扩展问题2:如何判断给定的前序遍历和中序遍历的结果是合理的?
思路:
问题1:搜索所有可能的情况,并调用扩展问题2的解决方案,判断此情况是否合理(剪枝操作),如果合法,则构造解
问题2:递归判断左右子树是否合理,递归的返回条件是到达叶子节点。
代码及测试情况如下:
/* * 编程之美重建二叉树,扩展问题1,2 * 扩展问题1:如果前序和中序的字母可能是相同的,怎么重构出所有可能的解? * 扩展问题2:如何判断给定的前序和中序遍历的结果是合理的? * * */ #include <iostream> #include <string> using namespace std; struct Node { Node *left; Node *right; char value; }; void pre_travel(Node *p) { if(p == NULL) return; cout << p->value << endl; pre_travel(p->left); pre_travel(p->right); } //枚举所有的情况,递归判断是否合法,如果递归到只剩一个叶子节点 //则肯定是合法的 bool isvalid(const char *preorder, const char *inorder, int len) { const char *leftend = inorder; if(len == 1) return true; for(int i=0; i<len; i++, leftend++){ if(*leftend == *preorder){ int leftlen = leftend - inorder; int rightlen = len - leftlen - 1; bool lres = false, rres = false; if(leftlen > 0){ lres = isvalid(preorder+1, inorder, leftlen); } if(rightlen > 0){ rres = isvalid(preorder+leftlen+1, inorder+leftlen+1, rightlen); } //如果leftlen和rightlen都大于零,则lres和rres必须都为true,此分割方法才算合法 if((leftlen > 0 && rightlen >0 && lres && rres) || (leftlen > 0 && rightlen <=0 && lres) || (left <=0 && rightlen > 0 && rres)){ return true; } } } return false; } //枚举法,在枚举的同时使用isvalid函数,排除非法情况 void rebuild(const char *preorder, const char *inorder, int len, Node **root) { if(preorder == NULL || inorder == NULL) return; if(*root == NULL){ Node *temp = new Node; temp->left = NULL; temp->right = NULL; temp->value = *preorder; *root = temp; } if(len == 1) return; const char *leftend = inorder; for(int i=0; i<len; i++, leftend++){ if(*leftend == *preorder){ int leftlen = leftend - inorder; int rightlen = len - leftlen - 1; if(leftlen > 0 && rightlen >0){ if(isvalid(preorder+1, inorder, leftlen) && isvalid(preorder+leftlen+1, inorder+leftlen+1, rightlen)){ rebuild(preorder+1, inorder, leftlen, &((*root)->left)); rebuild(preorder+leftlen+1, inorder+leftlen+1, rightlen, &((*root)->right)); } }else if(leftlen > 0 && rightlen <= 0){ if(isvalid(preorder+1, inorder, leftlen)) rebuild(preorder+1, inorder, leftlen, &((*root)->left)); }else if(leftlen <=0 && rightlen >0){ if(isvalid(preorder+leftlen+1, inorder+leftlen+1, rightlen)) rebuild(preorder+leftlen+1, inorder+leftlen+1, rightlen, &((*root)->right)); } } } } int main() { string pre1 = "abdefc"; string mid1 = "dbfeac"; string pre2 = "abdefc"; string mid2 = "dcfeab"; //有重复的字母 string pre3 = "aadcef"; string mid3 = "daaecf"; bool valid = isvalid(pre1.c_str(), mid1.c_str(), pre1.length()); cout << valid << endl; valid = isvalid(pre2.c_str(), mid2.c_str(), pre2.length()); cout << valid << endl; valid = isvalid(pre3.c_str(), mid3.c_str(), pre3.length()); cout << valid << endl; Node *root = NULL; rebuild(pre3.c_str(), mid3.c_str(), 6, &root); pre_travel(root); return 0; }
相关文章推荐
- 编程之美 3.9 重建二叉树 扩展问题
- 编程之美-重建二叉树扩展问题1 2
- 3.9重建二叉树(各种方案的分析比较及扩展问题的分析)
- 3.9重建二叉树(各种方案的分析比较及扩展问题的分析)
- 编程之美 3.10 分层遍历二叉树 扩展问题代码实现
- 《编程之美》读书笔记(十一):“求二叉树中节点的最大距离”扩展问题
- 编程之美--重建二叉树
- 编程之美--1.8--小飞的电梯调度问题--扩展问题--2--(M层电梯选择K层停靠)
- 编程之美3.11扩展问题 简单并带有错误的环形单链表检测代码
- 关于php扩展编程如何返回数组的问题
- 编程之美----扩展问题
- 3.10 分层遍历二叉树 扩展问题一、二
- 《剑指offer》问题7 重建二叉树 Java实现
- java编程求二叉树最大路径问题代码分析
- 编程之美--求数组的子数组之和的最大值--扩展问题
- (1.5.2.3)编程之美 寻找发帖水王 扩展问题
- 编程之美---快速寻找满足条件的两个数---扩展问题
- 编程之美 4.2 瓷砖覆盖地板 扩展问题
- [编程之美3.9]重建二叉树
- zz: windows 下编程 常见的 字符集的问题。