二叉树线索化
来源:互联网 发布:asc软件 编辑:程序博客网 时间:2024/06/05 19:23
二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只
能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。
为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。
enum PointerTag {THREAD, LINK};
template
struct BinaryTreeNode_Thd
{
T _data ; // 数据
BinaryTreeNode_Thd* _left; // 左孩子
BinaryTreeNode_Thd* _right; // 右孩子
PointerTag _leftTag ; // 左孩子线索标志
PointerTag _rightTag ; // 右孩子线索标志
};
#pragma onceenum PointerType{ THREAD, LINK,};template<class T>struct BinaryTreeNodeThd{ BinaryTreeNodeThd<T>* _left; BinaryTreeNodeThd<T>* _right; T _data; PointerType _leftType; PointerType _rightType; BinaryTreeNodeThd(const T& x) :_data(x) ,_left(NULL) ,_right(NULL) ,_leftType(LINK) ,_rightType(LINK) {}};template<class T, class Ref, class Ptr>struct BinaryTreeIterator{ typedef BinaryTreeNodeThd<T> Node; typedef BinaryTreeIterator<T, Ref, Ptr> Self; BinaryTreeIterator(Node* node) :_node(node) {} Ref operator*() { return _node->_data; } Ptr operator->() { return &(operator*()); } Self operator++(int) { Self tmp(*this); ++*this; return tmp; } Self& operator++() { if (_node->_rightType == THREAD) { _node = _node->_right; } else { Node* left = _node->_right; while (left->_leftType == LINK) { left = left->_left; } _node = left; } return *this; } Self operator--(int); Self& operator--() { if (_node->_leftType == THREAD) { _node = _node->_left; } else { Node* right = _node->_right; while (right->_rightType == LINK) { right = right->_right; } _node = right; } } bool operator!=(const Self& s) const { return _node != s._node; } Node* _node;};template<class T>class BinaryTreeThd{ typedef BinaryTreeNodeThd<T> Node;public: typedef BinaryTreeIterator<T, T&, T*> Iterator; typedef BinaryTreeIterator<T, const T&, const T*> ConstIterator; BinaryTreeThd(T* a, size_t n, const T& invalid) { size_t index = 0; _root = _CreateTree(a, n, invalid, index); } void InOrderThreading() { Node* prev = NULL; _InOrderThreading(_root, prev); if (prev) prev->_rightType = THREAD; } void InOrderThd() { Node* cur = _root; while (cur) { // 第一个需要访问的节点--最左节点 while (cur->_leftType == LINK) { cur = cur->_left; } cout<<cur->_data<<" "; // cur->right 1.子树(子问题) 2.Thread if (cur->_rightType == LINK) { cur = cur->_right; } else { while (cur->_rightType == THREAD) { cur = cur->_right; if (cur == NULL) { cout<<endl; return; } cout<<cur->_data<<" "; } // LINK -- 子问题 cur = cur->_right; } //while (cur->_rightType == THREAD) //{ // // 调到后继节点-直接访问后继 // cur = cur->_right; // cout<<cur->_data<<" "; //} // //// 子问题 //cur = cur->_right; } cout<<endl; } void PrevOrderThreading() { Node* prev = NULL; _PrevOrderThreading(_root, prev); } void PrevOrderThd() { Node* cur = _root; while (cur) { while (cur->_leftType == LINK) { cout<<cur->_data<<" "; cur = cur->_left; } cout<<cur->_data<<" "; cur = cur->_right; //while (cur->_rightType == THREAD) //{ // cur = cur->_right; // cout<<cur->_data<<" "; //} //// 子问题 //cur = cur->_right; } cout<<endl; } void PrevOrder() { _PrevOrder(_root); cout<<endl; } Iterator Begin() { Node* cur = _root; while (cur->_leftType == LINK) { cur = cur->_left; } return Iterator(cur); } Iterator End() { return NULL; }protected: void _PrevOrderThreading(Node* cur, Node* & prev) { if (cur == NULL) return; // if (cur->_left == NULL) { cur->_left = prev; cur->_leftType = THREAD; } if (prev && prev->_right == NULL) { prev->_right = cur; prev->_rightType = THREAD; } prev = cur; if (cur->_leftType == LINK) { _PrevOrderThreading(cur->_left, prev); } if (cur->_rightType == LINK) { _PrevOrderThreading(cur->_right, prev); } } void _InOrderThreading(Node* cur, Node* & prev) { if (cur == NULL) return; _InOrderThreading(cur->_left, prev); // root 在这出现顺序就是中序的顺序 if(cur->_left == NULL) { cur->_left = prev; cur->_leftType = THREAD; } if (prev && prev->_right == NULL) { prev->_right = cur; prev->_rightType = THREAD; } prev = cur; _InOrderThreading(cur->_right, prev); } Node* _CreateTree(T* a, size_t n, const T& invalid, size_t& index) { Node* root = NULL; if (index < n && a[index] != invalid) { root = new Node(a[index]); root->_left = _CreateTree(a, n, invalid, ++index); root->_right = _CreateTree(a, n, invalid, ++index); } return root; } void _PrevOrder(Node* root) { if (root == NULL) return; // ? cout<<root->_data<<" "; if (root->_leftType == LINK) { _PrevOrder(root->_left); } if (root->_rightType == LINK) { _PrevOrder(root->_right); } }protected: Node* _root;};void TestBinaryTreeThd(){ int array [10] = {1, 2, 3, '#', '#', 4, '#', '#', 5, 6}; BinaryTreeThd<int> t1(array, sizeof(array)/sizeof(array[0]), '#'); t1.InOrderThreading(); BinaryTreeThd<int>::Iterator it = t1.Begin(); while (it != t1.End()) { cout<<*it<<" "; ++it; } cout<<endl; BinaryTreeThd<int> t2(array, sizeof(array)/sizeof(array[0]), '#'); t2.PrevOrderThreading(); t2.PrevOrderThd(); int a1[15] ={1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8}; BinaryTreeThd<int> t3(a1, sizeof(a1)/sizeof(a1[0]), '#'); t3.InOrderThreading(); t3.InOrderThd(); BinaryTreeThd<int> t4(a1, sizeof(a1)/sizeof(a1[0]), '#'); t4.PrevOrderThreading(); t4.PrevOrderThd();}
阅读全文
1 0
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- AngularJS自定义服务
- C++学习——泛型编程
- 树莓派Pi2安装ROS Kinetic Kame开发环境(基于Ubuntu 16.04LTS)
- java中ArrayList的源码实现
- 私人文章
- 二叉树线索化
- Android 代码混淆语法讲解及常用模板
- OpenCV学习笔记(一)——Linux下的OpenCV配置
- “实现模拟三次密码输入”的场景的c程序
- 剑指offer第19题(顺时针打印矩阵)
- SPOJREPEATS-Repeats
- 明确问题,加以解决。
- Linux 基础学习篇1
- Mybatis学习笔记-关联表查询的问题 (一对多关联)