CLRS 10.4有根树的表示
2015-12-05 10:21
218 查看
10.4-1
10.4-2、10.4-3
给出先中后序的递归和非递归代码
10.4-4
和二叉树遍历没什么区别,见上。
10.4-5
采用类似中序遍历的方法,每个结点有三个指针,分别指向父结点,左右孩子结点。同时标记左右结点是否访问过,如果都访问过了,则说明当前节点的子树已经访问过,因此向上走。如果左右都没访问过,则向左一路到底。如果左边访问过了,右边没访问过,则向右移一位,再一路向左到底。
10.4-6
布尔变量判断此结点是否是最右结点,若是则指向父结点,不是则指向右兄弟,另外一个指针则指向左孩子。
10.4-2、10.4-3
给出先中后序的递归和非递归代码
#include <iostream> #include <stack> using std::cout; using std::endl; using std::stack; struct binTree { int key; binTree *left; binTree *right; binTree(int x):key(x),left(NULL),right(NULL){} }; void preorder(binTree *root) //先序遍历 { if(root != NULL) { cout << root->key << ' '; preorder(root->left); preorder(root->right); } } void inorder(binTree *root) //中序遍历 { if(root != NULL) { inorder(root->left); cout << root->key << ' '; inorder(root->right); } } void postorder(binTree *root) //后序遍历 { if(root != NULL) { postorder(root->left); postorder(root->right); cout << root->key << ' '; } } void non_recursive_preorder(binTree *root) { stack<binTree *> ptr; binTree *p = root; while(p || !ptr.empty()) { while(p) //p非空,输出然后继续向左子树走 { cout << p->key << ' '; ptr.push(p); p = p->left; } if(!ptr.empty()) //左子树空但栈不空,得到左子树的根,然后向右子树走 { p = ptr.top(); ptr.pop(); p = p->right; } } } void non_recursive_inorder(binTree *root) { stack<binTree *> ptr; binTree *p = root; while(p || !ptr.empty()) { while(p) //一直找到最左孩子 { ptr.push(p); p = p->left; } if(!ptr.empty()) //出栈,然后向右子树走 { p = ptr.top(); cout << p->key << ' '; ptr.pop(); p = p->right; } } } void non_recursive_postorder(binTree *root) { stack<binTree *> ptr; binTree *cur; binTree *pre = NULL; ptr.push(root); while(!ptr.empty()) { cur = ptr.top(); //当前结点无左右孩子或者左右孩子已经访问过了,输出当前结点 if((cur->left == NULL && cur->right == NULL) || pre && (pre == cur->left || pre == cur->right)) { cout << cur->key << ' '; ptr.pop(); pre = cur; } else //当前结点右子树和左子树分别压入栈 { if(cur->right != NULL) ptr.push(cur->right); if(cur->left != NULL) ptr.push(cur->left); } } }
10.4-4
和二叉树遍历没什么区别,见上。
10.4-5
采用类似中序遍历的方法,每个结点有三个指针,分别指向父结点,左右孩子结点。同时标记左右结点是否访问过,如果都访问过了,则说明当前节点的子树已经访问过,因此向上走。如果左右都没访问过,则向左一路到底。如果左边访问过了,右边没访问过,则向右移一位,再一路向左到底。
#include <iostream> using std::cout; using std::endl; struct binTree { int key; binTree *left; binTree *right; binTree *parent; binTree(int x):key(x),left(NULL),right(NULL),parent(NULL){} }; void non_recursive_traverse(binTree *root) { binTree *p = root; bool left = false, right = false; //判断当前结点的左孩子和右孩子是否已经访问过 while(!(p == root && left && right))//访问到root结点,退出 { if(left && right) //如果左右孩子都访问过,则向上走 { left = false; right = false; if(p->parent->left == p) //当前是父结点的左孩子 left = true; if(p->parent->right == p) { left = true; right = true; } p = p->parent; } else if (!right) //跳转到右边 { while(p->left != NULL && !left) //如果左边也没访问过,则一直向左走到底 p = p->left; cout << p->key << ' '; if(p->right != NULL) //如果右边有结点,则向右走 { p = p->right; left = false; right = false; } else //如果右边没有结点,就向上走 { left = false; right = false; if(p->parent->left == p) left = true; if(p->parent->right == p) { left = true; right = true; } p = p->parent; } } } }
10.4-6
布尔变量判断此结点是否是最右结点,若是则指向父结点,不是则指向右兄弟,另外一个指针则指向左孩子。
相关文章推荐
- 安装Hadoop系列 — 安装Eclipse
- CCBPM高级开发之类设计与数据库设计命名规则
- ADO_NET 数据库连接字符串大全
- 布线问题
- CCBPM关于工作流引擎授权功能说明
- [LeetCode] Largest Rectangle in Histogram 解题思路
- AngularJs Cookies 操作
- 命名空间比较好的博客
- 圆排列问题
- js精度丢失解决办法
- maven项目配置Project Facets时further configuration available不出来问题
- js精度丢失解决办法
- 安装Hadoop系列 — 安装Hadoop
- 第14周项目1-(3)验证二叉排序树相关算法
- n皇后问题
- 迄今为止最浮夸的代码编辑器插件
- 端口简介
- sql语句中trim
- ubuntu下安装bochs遇到的问题
- 静态图—类图、包图、对象图(2)