线索化二叉树C++

原创 2015年11月19日 10:15:31

线索化二叉树
1.创建二叉树
2.先序递归遍历输出二叉树
3.线索化二叉树
4.输出线索化二叉树

/*
线索化二叉树
	1.创建二叉树
	2.先序递归遍历输出二叉树
	3.线索化二叉树
	4.输出线索化二叉树
*/

#include<iostream>
#include<stack>
#include<string>
#include<fstream>
using namespace std;

class Node
{
public:
	char data;
	bool ltag, rtag;
	class Node *lchild, *rchild;
};

class Thread_Binary_Tree
{
public:

	Thread_Binary_Tree(){}
	~Thread_Binary_Tree(){}

	//创建二叉树
	void create_binary_tree(string filename)
	{
		ifstream readfile;
		string str;
		readfile.open(filename,ios::in);
		getline(readfile,str);
		cout << str << endl;
		Create_Tree(str);//创建二叉树
		readfile.close();
	}


	//先序递归输出二叉树
	void displayFront_tree()
	{
		cout << "先序递归输出" << endl;
		output_fro(t);//递归先序输出
		cout << endl;
	}

	//创建线索化二叉树
	void create_thread_Btree()
	{
		thread_root = CreateThread(t);
	}
	
	//输出线索化二叉树
	void display_thread_Btree()
	{
		cout << "中序线索化输出" << endl;
		output_thread(thread_root);
		cout << endl;
		cout << "中序线索化新根节点左右标记" << endl;
		cout << thread_root->ltag << "," << thread_root->rtag << endl;//输出中序线索化新根节点左右标记
	}
private:
	Node *t;
	Node *pre;
	Node *thread_root;
	//创建二叉树
	void Create_Tree(string str)
	{
		stack<Node *> m_stack;
		int k;
		Node *p;
		while (!str.empty())
		{
			if (str[0] == '(')
			{
				m_stack.push(p);
				k = 1;
			}
			else if (str[0] == ')')//必须使用if-else if
			{
				m_stack.pop();
			}
			else if (str[0] == ',')
			{
				k = 2;
			}
			else
			{
				p = (Node *)malloc(sizeof(Node));
				p->lchild = p->rchild = NULL;
				p->data = str[0];//将串首字符赋给data
				if (t == NULL)//处理根节点
				{
					t = p;
				}
				else
				{
					if (k == 1)
					{
						m_stack.top()->lchild = p;//左子树
					}
					if (k == 2)
					{
						m_stack.top()->rchild = p;//右子树
					}
				}
			}
			str.assign(str.substr(1, str.length() - 1));//构建新串,将串首字符除去
		}
	}

	//先序递归输出二叉树
	void output_fro(Node *t)
	{
		if (t == NULL)
		{
			return;
		}
		else
		{
			cout << t->data;
			if (t->lchild != NULL || t->rchild != NULL)
			{
				cout << "(";
				output_fro(t->lchild);//先序递归左子树
				if (t->rchild != NULL)
				{
					cout << ",";
				}
				output_fro(t->rchild);//先序递归右子树
				cout << ")";
			}
		}
	}

	//中序线索化二叉树
	void Thread(Node *&p)
	{
		if (p != NULL)
		{
			Thread(p->lchild);//向左直走
			if (p->lchild == NULL)//遍历到中序遍历输出的首节点且无左子节点
			{
				p->lchild = pre;//指向前驱节点
				p->ltag = true;
			}
			else//存在左子节点
			{
				p->ltag = false;
			}
			if (pre->rchild == NULL)//若右节点无子节点,则右指针指向后继节点
			{
				pre->rchild = p;
				pre->rtag = true;
			}
			else//存在右子节点
			{
				pre->rtag = false;
			}
			pre = p;//更新
			Thread(p->rchild);//处理右子树
		}
	}

	//创建线索化二叉树
	Node *CreateThread(Node *t)
	{
		Node *root;
		root = (Node *)malloc(sizeof(Node));//生成附加根节点
		root->ltag = false; root->rtag = true;
		root->rchild = t;
		if (t == NULL)//空树线索化
		{
			root->lchild = root;
		}
		else
		{
			root->lchild = t;
			pre = root;//pre初始化
			Thread(t);//线索化二叉树
			pre->rchild = root;//中序末节点
			pre->rtag = true;
			root->rchild = pre;//新生成根节点
			root->rtag = 1;//新生成根节点rtag=1;
		}
		return root;
	}

	//遍历输出线索化二叉树
	void output_thread(Node *t)
	{
		Node *p = t->lchild;
		while (p != t)
		{
			while (!p->ltag)
			{
				p = p->lchild;
			}
			cout << p->data << ends;
			
			while (p->rtag&&p->rchild != t)
			{
				p = p->rchild;
				cout << p->data << ends;
			}
			p = p->rchild;
		}
		
	}
};

int main()
{
	Thread_Binary_Tree m_tree;
	m_tree.create_binary_tree("data");//创建普通二叉树
	m_tree.displayFront_tree();//先序递归遍历输出
	m_tree.create_thread_Btree();//创建中序线索化二叉树
	m_tree.display_thread_Btree();//输出中序线索化二叉树
	return 0;
}
测试运行



版权声明:本文为博主原创文章,转载请注明出处,否则予以追究。

相关文章推荐

线索二叉树的原理以及创建和遍历(c++)

这是一篇非常好的关于线索二叉树的文章,内容详细到位,叙述清晰。作者是以为很认真、信息的人,估计花了不少时间和精力,向作者致敬! 引用地址:http://waret.iteye.com/blog/70...
  • wbcg111
  • wbcg111
  • 2016年03月26日 10:31
  • 1030

数据结构_树_二叉树的线索化_C++实现

"head.h" #include #define LINK 0//定义节点类型:指针 #define THREAD 1//定于节点类型:线索 using namespace std; //...

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

//线索二叉树的实现 #include "stdafx.h" #include using namespace std; enum flag{ Child, Thread }; ...

【C++】中序线索化二叉树及其遍历

二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。 ...
  • ZDF0414
  • ZDF0414
  • 2015年11月22日 13:40
  • 701

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

彻底理解线索二叉树

一、线索二叉树的原理     通过考察各种二叉链表,不管儿叉树的形态如何,空链域的个数总是多过非空链域的个数。准确的说,n各结点的二叉链表共有2n个链域,非空链域为n-1个,但其中的空链域却有n...

二叉树线索化以及线索化的先序、中序、后序遍历

二叉树线索化以及线索化的先序、中序、后序遍历 有详细的图解 和 程序代码 解读,以及 为什么要线索化二叉树...

数据结构-------------线索二叉树(c语言)

一、线索二叉树        如果二叉树的节点包含数据域和两个指针域( lchild 和 rchild ),当节点没有下一个节点时,将指针域赋值为空(NULL),但有时会造成很大的浪费,所以可以将空...

二叉树的线索化

线索二叉树(Threaded BinaryTree) 1.线索二叉树的基本概念       遍历二叉树是以一定规则将二叉树中的结点排列成一个线性序列,得到二叉树中结点的先序序列、中序序列或后序序列。 ...

线索二叉树原理及前序、中序线索化(Java版)

一、线索二叉树原理      前面介绍二叉树原理及特殊二叉树文章中提到,二叉树可以使用两种存储结构:顺序存储和二叉链表。在使用二叉链表的存储结构的过程中,会存在大量的空指针域,为了充分利用这些空指针域...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线索化二叉树C++
举报原因:
原因补充:

(最多只允许输入30个字)