关闭

C++实现中序线索二叉树

标签: 数据结构C++vs二叉树线索二叉树
241人阅读 评论(0) 收藏 举报
分类:
//线索二叉树的实现

#include "stdafx.h"
#include <iostream>

using namespace std;

enum flag{ Child, Thread };             //枚举类型,Child=0,Thread=1

template<typename T>
struct ThrNode{
	T data;
	ThrNode<T> *L_child, *R_child;
	flag L_tag, R_tag;
};

template<typename T>
class ThrBiTree{
public:
	ThrBiTree();    //初始化构造线索二叉树
	~ThrBiTree(){}
	ThrNode<T>* Creat_BiTree(ThrNode<T> *rt);    //建立二叉链表
	void MidOrder_Thread(ThrNode<T> *rt);
	void Mid_ThrBiTree(ThrNode<T> *rt, ThrNode<T> *pre);         //中序线索化
	ThrNode<T>* Next_Node(ThrNode<T> *p);       //查找结点p的后继结点
	ThrNode<T>* Pre_Node(ThrNode<T> *p);        //查找p的前驱结点
	ThrNode<T>* GetRoot(){ return root; }
	void Mid_Order(ThrNode<T> *rt);
private:
	ThrNode<T> *root;
};

template<typename T>
ThrBiTree<T>::ThrBiTree()
{ 
	root = Creat_BiTree(root);
	ThrNode<T>* pre = NULL;
	Mid_ThrBiTree(root, pre);
}

//先建立二叉链表,再遍历修改结点中的空指针,从而得到线索二叉链表
template<typename T>
ThrNode<T>* ThrBiTree<T>::Creat_BiTree(ThrNode<T> *rt){   
	T node_Value;
	cout << "输入结点值:";
	cin >> node_Value;
	if (node_Value == -1)
		rt = NULL;                            //空树
	else{
		rt = new ThrNode <T>;
		rt->data = node_Value;
		rt->L_tag = Child;                         //左右标志位均置为0
		rt->R_tag = Child;
		rt->L_child = Creat_BiTree(rt->L_child);  //递归建立左子树
		rt->R_child = Creat_BiTree(rt->R_child);  //递归建立右子树
	}
	return rt;
}

template<typename T>
void ThrBiTree<T>::Mid_ThrBiTree(ThrNode<T> *rt, ThrNode<T> *pre){
	ThrNode<T>* p = rt;
	if (p != NULL)
	{
		Mid_ThrBiTree(p->L_child, pre);          //递归左子树线索化
		cout << p->data << " ";                 //中序遍历输出
		if (p->L_child = NULL)                  //没有左孩子
		{
			p->L_tag = Thread;                 //前驱线索
			p->L_child = pre;                  //左孩子指针指向前驱
		}
		
		if (pre != NULL && pre->R_child == NULL)     //没有右孩子
		{
			pre->R_tag = Thread;  //后继线索
			pre->R_child = p; //前驱右孩子指针指向后继(当前结点p)
		}
		pre = p;             //pre始终是p的前驱,相当于p和pre各进行了一次中序遍历
		                    //p遍历时只改变结点的前驱指针域,pre遍历时只修改后继指针域
		Mid_ThrBiTree(p->R_child, pre);      //递归右子树线索化
	}
}

//*******************************************************************************

//编译通过,调用时出错,求指正
template<typename T>
ThrNode<T>* ThrBiTree<T>::Next_Node(ThrNode<T> *p){    //求结点p的后继
	ThrNode<T> *q;
	if (p->R_tag == Thread)         //右标志位为Thread,可直接得到后继结点
		q = p->R_child;
	else{                         //p存在右子树
		q = p->R_child;            //q指向p的右孩子
		while (q->L_tag == Child)       //查找最左下的结点
			q = q->L_child;
	}
	return q;
}

//编译通过,调用时出错,求指正
template<typename T>
ThrNode<T>* ThrBiTree<T>::Pre_Node(ThrNode<T> *p){   //求结点p的前驱
	ThrNode<T> *q;
	if (p->L_tag == Thread)
		q = p->L_child;
	else{
		q = p->L_child;
		while (q->R_tag == Child)
			q = q->R_child;
	}
	return q;
}

//编译通过,调用时出错,求指正
template<typename T>
void ThrBiTree<T>::Mid_Order(ThrNode<T> *rt){
	if (rt == NULL)
		return;
	ThrNode<T> *p = rt;
	cout << p->data << " ";
	while (p->R_child != NULL){
		if (p->R_tag == Thread){
			p = p->R_child;
			cout << p->data << " ";
		}
		else{
			p = p->R_child;
			while (p->L_tag == Child)
				p = p->L_child;
			cout << p->data << " ";
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	ThrBiTree<int> A;      //初始化没问题
	ThrNode<int> *rootNode = A.GetRoot();   //返回根结点
	cout << A.Next_Node(rootNode)->data << endl;    //调用出错,求指正
	cout << A.Pre_Node(rootNode)->data << endl;     
	A.Mid_Order(rootNode);
	return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3882次
    • 积分:162
    • 等级:
    • 排名:千里之外
    • 原创:13篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章存档
    最新评论