线索化二叉树
来源:互联网 发布:希腊经济知乎 编辑:程序博客网 时间:2024/06/14 04:13
中序线索化(递归):
图形解析:
代码如下:
//中序线索化 void InorderThreading() { Node* prev = NULL; _InoderThreading(_root, prev); }void _InoderThreading(Node* cur, Node* & prev) { if (cur) { _InoderThreading(cur->_left, prev); if (NULL == cur->_left)//当前节点的左节点需要线索化 { cur->_left = prev; cur->_leftType = THREAD; } if (prev && NULL == prev->_right)//当前节点的前驱的右节点需要线索化 { prev->_right = cur; prev->_rightType = THREAD; } prev = cur;//更新prev _InoderThreading(cur->_right, prev); } }
中序遍历中序线索化:
代码如下:
//中序遍历 void InOrder() { _InOrder(_root); cout << endl; }//中序线索二叉树的中序遍历算法 void InorderThd() { Node* cur = _root; while (cur) { //查找最左节点 while (cur->_leftType == LINK) { cur = cur->_left; } cout << cur->_data << " "; //方法1 while (cur->_rightType == THREAD) { cur = cur->_right; if (NULL == cur) { return; } cout << cur->_data << " "; } //执行到此处-->说明右节点为右子树 cur = cur->_right; } }
前序线索化二叉树:
void _PreOrderThreading(Node* cur,Node*& prev) { if (NULL == cur) { return; } if (NULL == cur->_left) { cur->_left = prev; cur->_leftType = THREAD; } if (prev && NULL == prev->_right) { prev->_right = cur; prev->_rightType = THREAD; } prev = cur;//更新prev的值 if (cur->_leftType == LINK)//因为是先线索化后进行递归,为了避免死循环,所以需要判断 { _PreOrderThreading(cur->_left, prev); } if (cur->_rightType == LINK) { _PreOrderThreading(cur->_right, prev); } }
前序遍历前序线索化二叉树:
前序线索化二叉树的前序遍历算法(下面的代码很坑、有问题):
//前序遍历二叉树 void PreOrderThd() { Node* cur = _root; while (cur) { //访问左子树 while (cur->_leftType == LINK) { cout << cur->_data << " "; cur = cur->_left; } //此时的cur->_leftType == THREAD cout << cur->_data << " "; //1.子问题 2.cur->_rightType = THREAD while (cur->_rightType == THREAD) { cur = cur->_right; cout << cur->_data << " "; } cur = cur->_right;//子问题 } }
测试代码1如下:
int array1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 }; BinaryTreeThd<int> bt1(array1, sizeof(array1) / sizeof(int), '#'); bt1.PreOrder(); bt1.PreOrderThreading(); bt1.PreOrderThd();
结果如下:
测试代码2如下:
int array[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 }; BinaryTreeThd<int> bt(array, sizeof(array) / sizeof(int), '#'); bt.PreOrder(); bt.PreOrderThreading(); bt.PreOrderThd();
很明显,结果不对,下面我们来仔细分析其中存在的问题:
将上面的程序改之:
//前序遍历二叉树 void PreOrderThd() { Node* cur = _root; while (cur) { //访问左子树 while (cur->_leftType == LINK) { cout << cur->_data << " "; cur = cur->_left; } //此时的cur->_leftType == THREAD cout << cur->_data << " "; cur = cur->_right; } }
测试代码如下:
void TestBinary(){ int array1[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 }; BinaryTreeThd<int> bt1(array1, sizeof(array1) / sizeof(int), '#'); bt1.PreOrder(); bt1.PreOrderThreading(); bt1.PreOrderThd(); cout << endl; int array[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 }; BinaryTreeThd<int> bt(array, sizeof(array) / sizeof(int), '#'); bt.PreOrder(); bt.PreOrderThreading(); bt.PreOrderThd();}
结果如下:
代码如下:
#pragma once#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include <assert.h>using namespace std;enum PointerType{ LINK, THREAD,};template<class T>struct BinaryTreeThdNode{ BinaryTreeThdNode(const T& value) :_data(value) , _left(NULL) , _right(NULL) , _leftType(LINK) , _rightType(LINK) {} T _data; BinaryTreeThdNode<T>* _left; BinaryTreeThdNode<T>* _right; PointerType _leftType;//标记是否需要线索化 PointerType _rightType;};template<class T>class BinaryTreeThd{ typedef BinaryTreeThdNode<T> Node;public: BinaryTreeThd(const Node* node) :_root(node) {} BinaryTreeThd(const T* arr, size_t size, const T& invalid) { size_t index = 0; _root = _CreatTree(arr, size, invalid, index); } //先序遍历 void PreOrder() { _PreOrder(_root); cout << endl; } //中序遍历 void InOrder() { _InOrder(_root); cout << endl; } //后序遍历 void PostOrder() { _PostOrder(_root); cout << endl; } //中序线索化 void InorderThreading() { Node* prev = NULL; _InoderThreading(_root, prev); }//中序线索二叉树的中序遍历算法 void InorderThd() { Node* cur = _root; while (cur) { //查找最左节点 while (cur->_leftType == LINK) { cur = cur->_left; } cout << cur->_data << " "; //方法1 while (cur->_rightType == THREAD) { cur = cur->_right; if (NULL == cur) { return; } cout << cur->_data << " "; } //执行到此处-->说明右节点为右子树 cur = cur->_right; } } //前序线索二叉树的前序遍历算法 void PreOrderThreading() { Node* prev = NULL; _PreOrderThreading(_root, prev); if (NULL == prev) { prev->_rightType = THREAD; } } void PreOrderThd() { if (NULL == _root) { return; } Node* cur = _root; while (cur) { //访问根节点 cout << cur->_data << " "; //访问左子树 while (cur->_leftType == LINK) { cur = cur->_left; cout << cur->_data << " "; } //此时的cur->_leftType == THREAD while (cur->_rightType == THREAD) { cur = cur->_right; cout << cur->_data << " "; } cur = cur->_right;//子问题 } } //后序线索化二叉树 void PostOrderThreading() { Node* prev = NULL; _PostOrderThreading(_root,prev); } //后序遍历 void PostOrderThd() { if (NULL == _root) { return; } Node* cur = NULL; while (cur) { while (LINK == cur->_leftType || Link == cur->_rightType) { if (LINK == cur->_leftType) { cur = cur->_left; } if (LINK == cur->_rightType) { cur = cur->_right; } } cout << cur->_data << " "; Node* p = NULL; } }protected: //左、右、根 void _PostOrderThreading(Node* cur,Node*& prev) { if (NULL == cur) { return; } _PostOrderThreading(cur->_left, prev); _PostOrderThreading(cur->_right, prev); if (NULL == cur->_left) { cur->_left = prev; cur->_leftType = THREAD; } if (prev && NULL == prev->_right) { prev->_right = cur; prev->_rightType = THREAD; } prev = cur;//更新prev的值 } void _PreOrderThreading(Node* cur,Node*& prev) { if (NULL == cur) { return; } if (NULL == cur->_left) { cur->_left = prev; cur->_leftType = THREAD; } if (prev && NULL == prev->_right) { prev->_right = cur; prev->_rightType = THREAD; } prev = cur;//更新prev的值 if (cur->_leftType == LINK)//因为是先线索化后进行递归,为了避免死循环,所以需要判断 { _PreOrderThreading(cur->_left, prev); } if (cur->_rightType == LINK) { _PreOrderThreading(cur->_right, prev); } } void _PreOrder(Node* root) { if (root) { cout << root->_data << " "; _PreOrder(root->_left); _PreOrder(root->_right); } } void _InOrder(Node* root) { if (root) { _InOrder(root->_left); cout << root->_data << " "; _InOrder(root->_right); } } void _PostOrder(Node* root) { if (root) { _PostOrder(root->_left); _PostOrder(root->_right); cout << root->_data << " "; } } void _InoderThreading(Node* cur, Node* & prev) { if (cur) { _InoderThreading(cur->_left, prev); if (NULL == cur->_left)//当前节点的左节点需要线索化 { cur->_left = prev; cur->_leftType = THREAD; } if (prev && NULL == prev->_right)//当前节点的前驱的右节点需要线索化 { prev->_right = cur; prev->_rightType = THREAD; } prev = cur;//更新prev _InoderThreading(cur->_right, prev); } } Node* _CreatTree(const T* arr, size_t size, const T& invalid, size_t& index) { Node* newRoot = _root; if (index < size && arr[index] != invalid) { newRoot = new Node(arr[index]); newRoot->_left = _CreatTree(arr, size, invalid, ++index); newRoot->_right = _CreatTree(arr, size, invalid, ++index); } return newRoot; }private: Node* _root;};前序线索化二叉树:void _PreOrderThreading(Node* cur,Node*& prev) { if (NULL == cur) { return; } if (NULL == cur->_left) { cur->_left = prev; cur->_leftType = THREAD; } if (prev && NULL == prev->_right) { prev->_right = cur; prev->_rightType = THREAD; } prev = cur;//更新prev的值 if (cur->_leftType == LINK)//因为是先线索化后进行递归,为了避免死循环,所以需要判断 { _PreOrderThreading(cur->_left, prev); } if (cur->_rightType == LINK) { _PreOrderThreading(cur->_right, prev); } }
中序线索化二叉树的迭代器:
template<class T>struct BinaryTreeThdIterator{ typedef BinaryTreeThdNode<T> Node; typedef BinaryTreeThdIterator<T> self; BinaryTreeThdIterator(Node* node) :_node(node) {} T& operator*() { return _node->_data; } T* operator->() { return &(_node->_data); } self& operator++() { //后继 if (_node->_rightType == THREAD) { _node = _node->_right; } else//子问题 { Node* cur = _node->_right; while (cur->_leftType == LINK) { cur = cur->_left; } _node = cur; } return *this; } bool operator!=(const self& cur)const { return _node != cur._node; } bool operator==(const self& cur)const { return _node == cur._node; } Node* _node;};
总结:
本文概要:1.中序线索化二叉树
2.中序遍历中序线索化二叉树
3.前序线索化二叉树
4.前序遍历前序线索化二叉树(易入坑)
5.中序线索化二叉树的迭代器
阅读全文
0 0
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 线索化二叉树
- 二叉树线索化
- 线索化二叉树
- 线索化二叉树
- sdut-离散题目18
- 【PHP】修改 配置php.ini上传文件大小的限制
- Linux操作系统基础
- 图的最短路径问题-07-图6 旅游规划
- 通过源码的方式编译hadoop的安装文件
- 线索化二叉树
- 【附源码工程】Unity3D 支持代价的A星寻路和优化(二叉堆,寻路节点合并,相邻节点预先存储)
- HDU 1421
- drawable汇总
- 离散10
- GitHub for Windows简单操作
- 多线程
- 数据库索引
- [leetcode]: 594. Longest Harmonious Subsequence