线索化二叉树的非递归遍历(用前驱结点和后继访问)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线索化二叉树的非递归遍历(用前驱结点和后继访问)相关的知识,希望对你有一定的参考价值。
#pragma once #include<iostream> using namespace std; enum PointTag { THREAD, LINK }; template<class T> struct BinaryTreeNodeThd { T _data; BinaryTreeNodeThd<T>* _left; BinaryTreeNodeThd<T>* _right; BinaryTreeNodeThd<T>* _parent; PointTag _leftTag; PointTag _rightTag; BinaryTreeNodeThd(const T& x) :_data(x) , _left(NULL) , _right(NULL) , _parent(NULL) , _leftTag(LINK) , _rightTag(LINK) {} }; template<class T> class BinaryTreeThd { protected: BinaryTreeNodeThd<T>* _CreateBinaryTree(T* a, size_t& index, const size_t size) { BinaryTreeNodeThd<T>* root = NULL; if (index < size&&a[index] != ‘#‘) { root = new BinaryTreeNodeThd<T>(a[index]); root->_left = _CreateBinaryTree(a, ++index, size); if (root->_left) root->_left->_parent = root; root->_right = _CreateBinaryTree(a, ++index, size); if (root->_right) root->_right->_parent = root; } return root; } void _Clear(BinaryTreeNodeThd<T>* root) { if (root) { if (root->_leftTag == LINK) _Clear(root->_left); if (root->_rightTag == LINK) _Clear(root->_right); delete root; } } void _InOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev) { if (cur == NULL) return; _InOrderThreading(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; _InOrderThreading(cur->_right, prev); } void _PreOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& 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) _PreOrderThreading(cur->_left, prev); if (cur->_rightTag == LINK) _PreOrderThreading(cur->_right, prev); } void _PostOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev) { if (cur == NULL) return; _PostOrderThreading(cur->_left, prev); _PostOrderThreading(cur->_right, prev); if (cur&&cur->_left == NULL) { cur->_leftTag = THREAD; cur->_left = prev; } if (prev&&prev->_right == NULL) { prev->_rightTag = THREAD; prev->_right = cur; } prev = cur; } public: BinaryTreeThd() :_root(NULL) {} BinaryTreeThd(T* a,size_t size) { size_t index = 0; _root=_CreateBinaryTree(a, index, size); } ~BinaryTreeThd() { _Clear(_root); _root = NULL; } void PreOrderThreading() { BinaryTreeNodeThd<T>* prev = NULL; _PreOrderThreading(_root, prev); } /*void PreOrderThd() { if (_root == NULL) return; BinaryTreeNodeThd<T>* cur = _root; while (cur) { cout << cur->_data << " "; while (cur&&cur->_leftTag != THREAD) { cur = cur->_left; cout << cur->_data << " "; } while (cur&&cur->_rightTag != LINK) { cur = cur->_right; cout << cur->_data << " "; } if (cur->_leftTag == LINK) cur = cur->_left; else cur = cur->_right; } cout << endl; }*/ //优化版前序遍历,发现规律,注意观察 void PreOrderThd() { if (_root == NULL) return; BinaryTreeNodeThd<T>*cur = _root; while (cur) { while (cur&&cur->_leftTag == LINK) { cout << cur->_data << " "; cur = cur->_left; } cout << cur->_data << " "; cur = cur->_right; } cout << endl; } void InOrderThreading() { BinaryTreeNodeThd<T>* prev = NULL; _InOrderThreading(_root, prev); } void InOrderThd() { if (_root == NULL) return; BinaryTreeNodeThd<T>* cur = _root; while (cur) { while (cur&&cur->_leftTag != THREAD) cur = cur->_left; cout << cur->_data << " "; while (cur&&cur->_rightTag != LINK) { cur = cur->_right; cout << cur->_data << " "; } cur = cur->_right; } cout << endl; } void PostOrderThreading() { BinaryTreeNodeThd<T>* prev = NULL; _PostOrderThreading(_root, prev); } //重点 void PostOrderThd() { if (_root == NULL) return; BinaryTreeNodeThd<T>* cur = _root->_left; BinaryTreeNodeThd<T>* prev = NULL; int flag = 0; while (cur != _root) { while (cur&&cur->_leftTag == LINK) { cur = cur->_left; } while (cur&&cur->_rightTag == THREAD) { cout << cur->_data << " "; prev = cur; cur = cur->_right; } if (_root == cur) { cout << _root->_data << " "; prev = _root; break; } while(cur&&_root!=cur&&cur->_rightTag == LINK&&cur->_right == prev) { cout << cur->_data << " "; prev = cur; cur = cur->_parent; } if (cur == _root) { if (flag == 0) flag = 1; else break; } if (cur&&cur->_rightTag == LINK&&cur != prev) cur = cur->_right; else { cout << cur->_data << " "; prev = cur; cur = cur->_parent; } } if(prev!=_root) cout << _root->_data << " "; cout << endl; } protected: BinaryTreeNodeThd<T>* _root; }; void Test3() { //注意测试用例 //int array[18] = { 1, 2, 3, 7, ‘#‘,‘#‘,‘#‘,4,8,‘#‘,‘#‘,9,‘#‘,‘#‘,5,6,‘#‘,10}; int array[10] = { 1, 2, 3, ‘#‘, ‘#‘, 4, ‘#‘, ‘#‘, 5, 6 }; //int array[15] = { 1, 2, ‘#‘, 3, ‘#‘, ‘#‘, 4, 5, ‘#‘, 6, ‘#‘, 7, ‘#‘, ‘#‘, 8 }; BinaryTreeThd<int> b2(array, 10); /*b2.InOrderThreading(); b2.InOrderThd();*/ /*b2.PreOrderThreading(); b2.PreOrderThd();*/ b2.PostOrderThreading(); b2.PostOrderThd(); } int main() { Test3(); system("pause"); return 0; }
本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1750536
以上是关于线索化二叉树的非递归遍历(用前驱结点和后继访问)的主要内容,如果未能解决你的问题,请参考以下文章