二叉树的线索化

来源:互联网 发布:软件项目工作汇报 编辑:程序博客网 时间:2024/06/07 18:03

线索化意义:

二叉树是非线性结构,遍历二叉树都是通过递归或者用栈辅助非递归来遍历的。如果我们知道一个节点的前驱和后继,那么我们就可直接遍历二叉树

设置二叉树节点的前驱和后继,就是线索化二叉树,我们利用指向左右子树的空指针存放节点的前驱和后继

线索化设计思路:

遍历二叉树,当遍历到一个节点的左节点或右节点为空时,设置它的前驱和后继,那么访问时直接可根据节点的前驱和后继来进行访问


代码:

#pragma once#include<iostream>#include<assert.h>using namespace std;enum PointerTag{LINK,THREAD};template<class T>struct BinaryTreeNode_Thd{BinaryTreeNode_Thd(const T& d):_data(d), _left(NULL), _right(NULL), _leftTag(LINK), _rightTag(LINK){}T _data;BinaryTreeNode_Thd<T>* _left;//左孩子BinaryTreeNode_Thd<T>* _right;//右孩子PointerTag _leftTag;//左孩子线索化标志PointerTag _rightTag;//右孩子线索化标志};template<class T>class BinaryTreeThd{typedef  BinaryTreeNode_Thd<T> Node;public:BinaryTreeThd(const T* a, size_t size, const T& invalid):_root(NULL){size_t index = 0;_root=_CreatTree(a, size, index, invalid);}void InOrderTheading()//中序线索化{Node* prev = NULL;_InOrderTheading(_root,prev);}void InOrderThd()//中序遍历{Node* cur = _root;while (cur){while (cur->_leftTag == LINK)//找树的最左节点{cur = cur->_left;}cout << cur->_data << " ";while (cur->_rightTag == THREAD){cur = cur->_right;cout << cur->_data << " ";}cur = cur->_right;}cout << endl;}void PrevOrderTheading()//前序线索化{Node* prev = NULL;_PrevOrderTheading(_root, prev);}void PrevOrderThd()//前序遍历{Node* cur = _root;while (cur){while (cur->_leftTag == LINK){cout << cur->_data << " ";cur = cur->_left;}cout << cur->_data << " ";cur = cur->_right;}}void PostOrderTheading()//后序线索化{Node* prev = NULL;_PostOrderTheading(_root, prev);}protected:Node* _CreatTree(const T *a, size_t size, size_t &index, const T& invalid)//建立二叉树{assert(a);Node* node = NULL;if (a[index] != invalid && index < size){    node= new Node(a[index]);node->_left = _CreatTree(a, size, ++index, invalid);node->_right = _CreatTree(a, size, ++index, invalid);}return node;}void _InOrderTheading(Node *cur, Node* &prev)//递归方法中序线索化{if (cur == NULL)return;_InOrderTheading(cur->_left, prev);if (cur->_left == NULL)//线索化前驱{cur->_leftTag = THREAD;cur->_left = prev;}if (prev && prev->_right == NULL)//线索化后继,这里由于本次线索化时并不知道其后继是哪里,//因此后继通过线索化下各节点的前驱时进行线索化{prev->_rightTag = THREAD;prev->_right = cur;}prev = cur;_InOrderTheading(cur->_right, prev);}void _PrevOrderTheading(Node *cur, Node* &prev)//递归方法前序线索化{if (cur == NULL)return;if (cur->_left == NULL){cur->_leftTag = THREAD;cur->_left = prev;}if (prev && prev->_right == NULL){prev->_rightTag = THREAD;prev->_right = cur;}prev = cur;if (cur->_leftTag==LINK)_PrevOrderTheading(cur->_left, prev);if (cur->_rightTag==LINK)_PrevOrderTheading(cur->_right, prev);}void _PostOrderTheading(Node *cur, Node* &prev)//递归方法中序线索化{if (cur == NULL)return;_PostOrderTheading(cur->_left, prev);_PostOrderTheading(cur->_right, prev);if (cur->_left == NULL){cur->_leftTag = THREAD;cur->_left = prev;}if (prev && prev->_right == NULL){prev->_rightTag = THREAD;prev->_right = cur;}prev = cur;}private:Node* _root;};


0 0
原创粉丝点击