二叉树的线索化
2016-04-10 17:29
274 查看
//本次练习的是 二叉树线索化的 前·中·后序 《 线索化 》 的递归和非递归实现
#include<iostream>
using namespace std;
enum Type
{
LINK,
THREAD
};
template<class T>
struct BinaryTreeNode
{
T _date;
BinaryTreeNode<T>* _left;
Type _leftType;
BinaryTreeNode<T>* _right;
Type _rightType;
BinaryTreeNode<T>* _parent;
BinaryTreeNode(const T& date)
:_date(date)
, _left(NULL)
, _leftType(LINK)
, _right(NULL)
, _rightType(LINK)
, _parent(NULL)
{}
};
template<class T>
class BinaryTreeThread
{
public:
BinaryTreeThread()
{};
BinaryTreeThread(const T* arr, size_t size)
{
size_t index = 0;
_root = _Create(arr, index, size);
}
// 以下用的是 递归
void InOrderThread() //中序线索化
{
BinaryTreeNode<T>* prev = NULL;
_InOrderThread(_root,prev);
}
void InOrder() //中序遍历
{
_InOrder(_root);
cout << endl;
}
void PrevOrderThread() //前序线索化
{
BinaryTreeNode<T>* prev = NULL;
_PrevOrderThread(_root,prev);
}
void PrevOrder() //前序遍历
{
_PrevOrder(_root);
cout << endl;
}
void LastOrderThread() //后序线索化
{
BinaryTreeNode<T>* prev = NULL;
_LastOrderThread(_root, prev);
}
void LastOrder() //后序遍历
{
_LastOrder(_root);
cout << endl;
}
//以下用的不是递归
void InOrder_Not() //中序线索化
{
_InOrder_Not(_root);
cout << endl;
}
void PrevOrder_Not() //前序线索化
{
_PrevOrder_Not(_root);
cout << endl;
}
void LastOrder_Not() //后序线索化
{
_LastOrder_Not(_root);
}
// 以下用的是 递归
protected:
BinaryTreeNode<T>* _Create(const T* arr, size_t& index, size_t size)
{
if (index >= size || arr[index] == '#')
{
return NULL;
}
BinaryTreeNode<T>* root = new BinaryTreeNode<T>(arr[index]);
root->_left = _Create(arr, ++index, size);
if (root->_left != NULL)
{
root->_left->_parent = root;
}
root->_right = _Create(arr, ++index, size);
if (root->_right != NULL)
{
root->_right->_parent = root;
}
return root;
}
void _InOrderThread(BinaryTreeNode<T>* root,BinaryTreeNode<T>*& prev) //注意 加 引用
{
if (root == NULL)
{
return;
}
_InOrderThread(root->_left,prev); //递归左
if (root != NULL && root->_left == NULL) //左链接
{
root->_leftType = THREAD;
root->_left = prev;
}
if (prev != NULL && prev->_right == NULL) //右链接
{
prev->_rightType = THREAD;
prev->_right = root;
}
prev = root;
_InOrderThread(root->_right,prev); //递归右
}
void _InOrder(const BinaryTreeNode<T>* root)
{
if (root == NULL)
{
return;
}
if (root->_leftType == LINK)
{
_InOrder(root->_left);
}
cout << root->_date << " ";
if (root->_rightType == LINK)
{
_InOrder(root->_right);
}
}
void _PrevOrderThread(BinaryTreeNode<T>* root, BinaryTreeNode<T>*& prev)
{
if (root == NULL)
{
return;
}
if (root != NULL && root->_left == NULL)
{
root->_leftType = THREAD;
root->_left = prev;
}
if (prev != NULL && prev->_right == NULL)
{
prev->_rightType = THREAD;
prev->_right = root;
}
prev = root;
if (root->_leftType == LINK) //这个节点已经线索化 所以要判断为LINK
{
_PrevOrderThread(root->_left, prev);
}
if (root->_rightType == LINK) //这个节点已经线索化
{
_PrevOrderThread(root->_right, prev);
}
}
void _PrevOrder(BinaryTreeNode<T>* root)
{
if (root == NULL)
{
return;
}
cout << root->_date<<" ";
if (root->_leftType == LINK)
{
_PrevOrder(root->_left);
}
if (root->_rightType == LINK)
{
_PrevOrder(root->_right);
}
}
void _LastOrderThread(BinaryTreeNode<T>* root, BinaryTreeNode<T>*& prev)
{
if (root == NULL)
{
return;
}
_LastOrderThread(root->_left,prev);
_LastOrderThread(root->_right,prev);
if (root != NULL && root->_left == NULL)
{
root->_leftType = THREAD;
root->_left = prev;
}
if (prev != NULL && prev->_right == NULL)
{
prev->_rightType = THREAD;
prev->_right = root;
}
prev = root;
}
void _LastOrder(BinaryTreeNode<T>* root)
{
if (root == NULL)
{
return;
}
if (root->_leftType == LINK)
{
_LastOrder(root->_left);
}
if (root->_rightType == LINK)
{
_LastOrder(root->_right);
}
cout << root->_date << " ";
}
// 以下用的不是递归
protected:
void _InOrder_Not(BinaryTreeNode<T>* root)
{
BinaryTreeNode<T>* cur = root;
while (cur != NULL)
{
while (cur != NULL && cur->_leftType == LINK)
{
cur = cur->_left;
}
cout << cur->_date << " ";
while (cur != NULL && cur->_rightType == THREAD)
{
cur = cur->_right;
cout << cur->_date << " ";
}
cur = cur->_right;
}
}
void _PrevOrder_Not(BinaryTreeNode<T>* root)
{
BinaryTreeNode<T>* cur = root;
while (cur != NULL)
{
cout << cur->_date << " ";
while (cur != NULL && cur->_leftType == LINK)
{
cur = cur->_left;
cout << cur->_date << " ";
}
while (cur != NULL && cur->_rightType == THREAD)
{
cur = cur->_right;
cout << cur->_date << " ";
}
cur = cur->_right;
}
}
void _LastOrder_Not(BinaryTreeNode<T>* root) //关键问题:1.判断一个节点已遍历 2.找到下一个节点
{
if (_root == NULL)
{
return;
}
BinaryTreeNode<T>* cur = root->_left;
BinaryTreeNode<T>* prev = NULL;
while (cur != _root)
{
while (cur != NULL && cur->_leftType == LINK && cur->_left != prev)// 当左子节点已经遍历完成就往右走
{
cur = cur->_left; //跳到最左节点
}
if (cur != NULL && cur->_rightType == THREAD)
{
cout << cur->_date << " ";
prev = cur;
cur = cur->_right;
}
if (cur == _root) //如果跳到了_root 就表示已经遍历完成
{
cout << cur->_date << " ";
break;
}
//此时 右树已经遍历完成
if (cur != NULL && cur->_rightType == LINK && cur->_right == prev)//如果根节点的右子树已经遍历完成 则跳到根节点的父亲节点
{
cout << cur->_date << " ";
prev = cur;
cur = cur->_parent;
}
/*if (cur != NULL && cur->_leftType == LINK && cur->_left == prev)
{
cout << cur->_date << " ";
prev = cur;
cur = cur->_right;
}*/
if (cur != NULL && cur->_rightType == LINK)
{
cur = cur->_right;
}
}
}
protected:
BinaryTreeNode<T>* _root;
};
void Test1()
{
int arr[10] = { 1, 2, 3, '#','#', 4, '#', '#', 5, 6 };
BinaryTreeThread<int> t1(arr, 10);
t1.InOrderThread();
t1.InOrder();
t1.InOrder_Not();
cout << endl;
BinaryTreeThread<int> t2(arr, 10);
t2.PrevOrderThread();
t2.PrevOrder();
t2.PrevOrder_Not();
cout << endl;
BinaryTreeThread<int> t3(arr, 10);
t3.LastOrderThread();
t3.LastOrder();
t3.LastOrder_Not();
}
int main()
{
Test1();
return 0;
}
#include<iostream>
using namespace std;
enum Type
{
LINK,
THREAD
};
template<class T>
struct BinaryTreeNode
{
T _date;
BinaryTreeNode<T>* _left;
Type _leftType;
BinaryTreeNode<T>* _right;
Type _rightType;
BinaryTreeNode<T>* _parent;
BinaryTreeNode(const T& date)
:_date(date)
, _left(NULL)
, _leftType(LINK)
, _right(NULL)
, _rightType(LINK)
, _parent(NULL)
{}
};
template<class T>
class BinaryTreeThread
{
public:
BinaryTreeThread()
{};
BinaryTreeThread(const T* arr, size_t size)
{
size_t index = 0;
_root = _Create(arr, index, size);
}
// 以下用的是 递归
void InOrderThread() //中序线索化
{
BinaryTreeNode<T>* prev = NULL;
_InOrderThread(_root,prev);
}
void InOrder() //中序遍历
{
_InOrder(_root);
cout << endl;
}
void PrevOrderThread() //前序线索化
{
BinaryTreeNode<T>* prev = NULL;
_PrevOrderThread(_root,prev);
}
void PrevOrder() //前序遍历
{
_PrevOrder(_root);
cout << endl;
}
void LastOrderThread() //后序线索化
{
BinaryTreeNode<T>* prev = NULL;
_LastOrderThread(_root, prev);
}
void LastOrder() //后序遍历
{
_LastOrder(_root);
cout << endl;
}
//以下用的不是递归
void InOrder_Not() //中序线索化
{
_InOrder_Not(_root);
cout << endl;
}
void PrevOrder_Not() //前序线索化
{
_PrevOrder_Not(_root);
cout << endl;
}
void LastOrder_Not() //后序线索化
{
_LastOrder_Not(_root);
}
// 以下用的是 递归
protected:
BinaryTreeNode<T>* _Create(const T* arr, size_t& index, size_t size)
{
if (index >= size || arr[index] == '#')
{
return NULL;
}
BinaryTreeNode<T>* root = new BinaryTreeNode<T>(arr[index]);
root->_left = _Create(arr, ++index, size);
if (root->_left != NULL)
{
root->_left->_parent = root;
}
root->_right = _Create(arr, ++index, size);
if (root->_right != NULL)
{
root->_right->_parent = root;
}
return root;
}
void _InOrderThread(BinaryTreeNode<T>* root,BinaryTreeNode<T>*& prev) //注意 加 引用
{
if (root == NULL)
{
return;
}
_InOrderThread(root->_left,prev); //递归左
if (root != NULL && root->_left == NULL) //左链接
{
root->_leftType = THREAD;
root->_left = prev;
}
if (prev != NULL && prev->_right == NULL) //右链接
{
prev->_rightType = THREAD;
prev->_right = root;
}
prev = root;
_InOrderThread(root->_right,prev); //递归右
}
void _InOrder(const BinaryTreeNode<T>* root)
{
if (root == NULL)
{
return;
}
if (root->_leftType == LINK)
{
_InOrder(root->_left);
}
cout << root->_date << " ";
if (root->_rightType == LINK)
{
_InOrder(root->_right);
}
}
void _PrevOrderThread(BinaryTreeNode<T>* root, BinaryTreeNode<T>*& prev)
{
if (root == NULL)
{
return;
}
if (root != NULL && root->_left == NULL)
{
root->_leftType = THREAD;
root->_left = prev;
}
if (prev != NULL && prev->_right == NULL)
{
prev->_rightType = THREAD;
prev->_right = root;
}
prev = root;
if (root->_leftType == LINK) //这个节点已经线索化 所以要判断为LINK
{
_PrevOrderThread(root->_left, prev);
}
if (root->_rightType == LINK) //这个节点已经线索化
{
_PrevOrderThread(root->_right, prev);
}
}
void _PrevOrder(BinaryTreeNode<T>* root)
{
if (root == NULL)
{
return;
}
cout << root->_date<<" ";
if (root->_leftType == LINK)
{
_PrevOrder(root->_left);
}
if (root->_rightType == LINK)
{
_PrevOrder(root->_right);
}
}
void _LastOrderThread(BinaryTreeNode<T>* root, BinaryTreeNode<T>*& prev)
{
if (root == NULL)
{
return;
}
_LastOrderThread(root->_left,prev);
_LastOrderThread(root->_right,prev);
if (root != NULL && root->_left == NULL)
{
root->_leftType = THREAD;
root->_left = prev;
}
if (prev != NULL && prev->_right == NULL)
{
prev->_rightType = THREAD;
prev->_right = root;
}
prev = root;
}
void _LastOrder(BinaryTreeNode<T>* root)
{
if (root == NULL)
{
return;
}
if (root->_leftType == LINK)
{
_LastOrder(root->_left);
}
if (root->_rightType == LINK)
{
_LastOrder(root->_right);
}
cout << root->_date << " ";
}
// 以下用的不是递归
protected:
void _InOrder_Not(BinaryTreeNode<T>* root)
{
BinaryTreeNode<T>* cur = root;
while (cur != NULL)
{
while (cur != NULL && cur->_leftType == LINK)
{
cur = cur->_left;
}
cout << cur->_date << " ";
while (cur != NULL && cur->_rightType == THREAD)
{
cur = cur->_right;
cout << cur->_date << " ";
}
cur = cur->_right;
}
}
void _PrevOrder_Not(BinaryTreeNode<T>* root)
{
BinaryTreeNode<T>* cur = root;
while (cur != NULL)
{
cout << cur->_date << " ";
while (cur != NULL && cur->_leftType == LINK)
{
cur = cur->_left;
cout << cur->_date << " ";
}
while (cur != NULL && cur->_rightType == THREAD)
{
cur = cur->_right;
cout << cur->_date << " ";
}
cur = cur->_right;
}
}
void _LastOrder_Not(BinaryTreeNode<T>* root) //关键问题:1.判断一个节点已遍历 2.找到下一个节点
{
if (_root == NULL)
{
return;
}
BinaryTreeNode<T>* cur = root->_left;
BinaryTreeNode<T>* prev = NULL;
while (cur != _root)
{
while (cur != NULL && cur->_leftType == LINK && cur->_left != prev)// 当左子节点已经遍历完成就往右走
{
cur = cur->_left; //跳到最左节点
}
if (cur != NULL && cur->_rightType == THREAD)
{
cout << cur->_date << " ";
prev = cur;
cur = cur->_right;
}
if (cur == _root) //如果跳到了_root 就表示已经遍历完成
{
cout << cur->_date << " ";
break;
}
//此时 右树已经遍历完成
if (cur != NULL && cur->_rightType == LINK && cur->_right == prev)//如果根节点的右子树已经遍历完成 则跳到根节点的父亲节点
{
cout << cur->_date << " ";
prev = cur;
cur = cur->_parent;
}
/*if (cur != NULL && cur->_leftType == LINK && cur->_left == prev)
{
cout << cur->_date << " ";
prev = cur;
cur = cur->_right;
}*/
if (cur != NULL && cur->_rightType == LINK)
{
cur = cur->_right;
}
}
}
protected:
BinaryTreeNode<T>* _root;
};
void Test1()
{
int arr[10] = { 1, 2, 3, '#','#', 4, '#', '#', 5, 6 };
BinaryTreeThread<int> t1(arr, 10);
t1.InOrderThread();
t1.InOrder();
t1.InOrder_Not();
cout << endl;
BinaryTreeThread<int> t2(arr, 10);
t2.PrevOrderThread();
t2.PrevOrder();
t2.PrevOrder_Not();
cout << endl;
BinaryTreeThread<int> t3(arr, 10);
t3.LastOrderThread();
t3.LastOrder();
t3.LastOrder_Not();
}
int main()
{
Test1();
return 0;
}
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- 举例讲解C语言程序中对二叉树数据结构的各种遍历方式
- C++非递归队列实现二叉树的广度优先遍历
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#非递归先序遍历二叉树实例
- C++将二叉树转为双向链表及判断两个链表是否相交
- C++非递归建立二叉树实例
- C语言实现找出二叉树中某个值的所有路径的方法
- C++实现二叉树遍历序列的求解方法
- C语言实现二叉树遍历的迭代算法
- C++实现查找二叉树中和为某一值的所有路径的示例
- 用C语言判断一个二叉树是否为另一个的子结构
- C++实现二叉树非递归遍历方法实例总结
- C++二叉树结构的建立与基本操作
- 深入遍历二叉树的各种操作详解(非递归遍历)
- JavaScript数据结构和算法之二叉树详解
- java使用归并删除法删除二叉树中节点的方法