编程之美-重建二叉树扩展问题1 2
2011-08-15 14:43
423 查看
编程之美3.9:重建二叉树
扩展问题1:如果前序和中序遍历的字母有重复的,那么怎么构造所有可能的解呢?
扩展问题2:如何判断给定的前序遍历和中序遍历的结果是合理的?
思路:
问题1:搜索所有可能的情况,并调用扩展问题2的解决方案,判断此情况是否合理(剪枝操作),如果合法,则构造解
问题2:递归判断左右子树是否合理,递归的返回条件是到达叶子节点。
代码及测试情况如下:
扩展问题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 重建二叉树 扩展问题
- [zz]编程之美-重建二叉树扩展问题1 2
- 3.9重建二叉树(各种方案的分析比较及扩展问题的分析)
- 3.9重建二叉树(各种方案的分析比较及扩展问题的分析)
- 编程之美 3.10 分层遍历二叉树 扩展问题代码实现
- 编程之美-3.9-重建二叉树
- 关于php扩展编程如何返回数组的问题
- 《剑指offer》问题7 重建二叉树 Java实现
- 【剑指Offer面试编程题】题目1385:重建二叉树--九度OJ
- 编程之美-判断两个链表是否相交 (涵其扩展问题)
- 3.10 分层遍历二叉树 扩展问题一、二
- 编程之美 2.7 最大公约数 扩展问题之逆转一个整数的二进制表示
- 编程之美 求数组的子数组之和的最大值(包含扩展问题解答)
- 编程之美---小飞的电梯调度问题 1.8 扩展2
- 编程之美-重建二叉树方法整理
- 最近碰到个问题,关于php扩展编程如何返回数组的问题
- 编程之美--高效率算出1的数目之扩展问题
- 第七章解决二叉树的编程问题
- 编程之美 - 寻找灌水王及扩展问题
- 《编程之美》读书笔记(十一):“求二叉树中节点的最大距离”扩展问题