给出二叉树,将二叉树进行中序线索化,在根据中序线索化二叉树,找出给定节点的前序后继节点,和给出节点的后序后继节点

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_28633157/article/details/49945955

该程序,最部分功能进行了详细的说明,在给别程序块中给出了详细的算法和注释

#ifndef BINARYTREENODE_H
#define BINARYTREENODE_H
template<typename T>
class BinaryTreeNode{
public:
	T data;
	int leftTag;
	int rightTag;
	BinaryTreeNode<T>* leftChild;
	BinaryTreeNode<T>* rightChild;
	BinaryTreeNode<T>* parent;
	BinaryTreeNode(){

	}
	BinaryTreeNode(const T& val, int leftTag, int rightTag, BinaryTreeNode<T>* str, BinaryTreeNode<T>* ptr,BinaryTreeNode<T>* p) :data(val), leftTag(leftTag), rightTag(rightTag), leftChild(str), rightChild(ptr),parent(p){

	}
};
#endif
#ifndef THREADBINARYTREE_H
#define THREADBINARYTREE_H
#include"BinaryTreeNode.h"
#include<iostream>
#include<queue>
using namespace std;
template<typename T>
class ThreadBinaryTree{
private:
	BinaryTreeNode<T>* root;
	BinaryTreeNode<T>* pre;
private:
	void Clear(BinaryTreeNode<T>* &str);
	void Creat();
	void AddLeaf(BinaryTreeNode<T>* &str);
	void PrintIorder()const;
	void ThreadTree()const;
	void ThreadIonderTree(BinaryTreeNode<T>* str,BinaryTreeNode<T>* ptr);
	void PrintVal(BinaryTreeNode<T>* str)const;
	BinaryTreeNode<T>* Find(const T& val)const;
	//在中序序列下,找到给定节点的前序后继节点
	BinaryTreeNode<T>* InorderSuccessor(BinaryTreeNode<T>* str);
	//在中序线索二叉树中找出给定节点的后序后继
	BinaryTreeNode<T>* PostIonderSuccessor(BinaryTreeNode<T>* str);
public:
	ThreadBinaryTree();
	~ThreadBinaryTree();
	void simulate();
};
template<typename T>
ThreadBinaryTree<T>::ThreadBinaryTree()
{
	this->root = NULL;
	this->pre = NULL;
}
template<typename T>
ThreadBinaryTree<T>::~ThreadBinaryTree()
{
	this->Clear(this->root);
}
template<typename T>
void ThreadBinaryTree<T>::Clear(BinaryTreeNode<T>* &str)
{
	queue<BinaryTreeNode<T>*>node;
	if (str == NULL)
		return;
	node.push(str);
	while (!node.empty())
	{
		str = node.front();
		node.pop();
		if (str->leftChild&&str->leftTag == 0)
			node.push(str->leftChild);
		if (str->rightChild&&str->rightTag == 0)
			node.push(str->rightChild);
		delete str;
	}
	str = NULL;
}
template<typename T>
void ThreadBinaryTree<T>::Creat()
{
	this->AddLeaf(this->root);
}
template<typename T>
void ThreadBinaryTree<T>::AddLeaf(BinaryTreeNode<T>* &str)
{
	T val;
	if (this->root == NULL)
	{
		cout << "input the root :";
	}
	cin >> val;
	if (val == '#')
	{
		str = NULL;
		return;
	}
	str = new BinaryTreeNode<T>(val, 0, 0, NULL, NULL, NULL);
	cout << "input the " << str->data << " leftChild :";
	AddLeaf(str->leftChild);
	cout << "input the " << str->data << " rigthChild :";
	AddLeaf(str->rightChild);
}
template<typename T>
void ThreadBinaryTree<T>::PrintIorder()const
{
	if (this->root == NULL)
	{
		cout << "the tree is empty" << endl;
		return;
	}
	BinaryTreeNode<T>* str = this->root;
	queue<BinaryTreeNode<T>*>node;
	node.push(str);
	while (!node.empty())
	{
		str = node.front();
		node.pop();
		if (str->leftChild)
		{
			node.push(str->leftChild);
			str->leftChild->parent = str;
		}
		if (str->rightChild)
		{
			node.push(str->rightChild);
			str->rightChild->parent = str;
		}
		cout << str->data << " ";
	}
}
template<typename T>
void ThreadBinaryTree<T>::simulate()
{
	this->Creat();
	this->PrintIorder();
	cout << endl;
	cout << "输入你要查找的元素:";
	T val;
	cin >> val;
	BinaryTreeNode<T>* str = this->Find(val);
	this->ThreadIonderTree(this->root, this->pre);
	cout << "输出" << val << "的前序后继";
	this->PrintVal(this->InorderSuccessor(str));
	cout << endl;
	cout << "输出" << val << "的后序后继";
	this->PrintVal(this->PostIonderSuccessor(str));
}
template<typename T>
void ThreadBinaryTree<T>::ThreadIonderTree(BinaryTreeNode<T>* str,BinaryTreeNode<T>* ptr)
{
	BinaryTreeNode<T>* current = str;
	if (current != NULL)
	{
		//在中徐线索化的过程中,值需要考虑到两种情况
		//首先明确中序线索化的过程   左->中->右,这就是中序线索化的过程
		//所以中序遍历过程中的第一个节点应该是左子树中的“最左的节点”
		//所以情况为两种
		//1:如果该节点的左子树为空,则执行current->leftChild=pre;current->leftTag=1;
		//2:如果pre节点存在,且pre节点的右子树不存在,则说明该节点应该是左子树中的“最右子树”或者是右子树中的“最右子树”
		//执行一下过程,pre->rightChild=root;pre->rightTag=1;
		ThreadIonderTree(current->leftChild, pre);
		if (current->leftChild == NULL)
		{
			current->leftChild = pre;
			current->leftTag = 1;
		}
		if ((pre) && pre->rightChild == NULL)
		{
			pre->rightChild = this->root;
			pre->rightTag = 1;
		}
		pre = current;
		ThreadIonderTree(current->rightChild, pre);
	}
}
template<typename T>
void ThreadBinaryTree<T>::PrintVal(BinaryTreeNode<T>* str)const
{
	if (str == NULL)
	{
		cout << "该节点没有前序后继结点" << endl;
		return;
	}
	cout << str->data << endl;
}
template<typename T>
BinaryTreeNode<T>* ThreadBinaryTree<T>::Find(const T& val)const
{
	BinaryTreeNode<T>* str = this->root;
	if (str == NULL)
	{
		cout << "the tre is empty" << endl;
		exit(true);
	}
	queue<BinaryTreeNode<T>*>node;
	node.push(str);
	while (!node.empty())
	{
		str = node.front();
		node.pop();
		if (str->leftChild)
			node.push(str->leftChild);
		if (str->rightChild)
			node.push(str->rightChild);
		if (str->data == val)
		{
			break;
		}
	}
	return str;
}
template<typename T>
BinaryTreeNode<T>* ThreadBinaryTree<T>::InorderSuccessor(BinaryTreeNode<T>* str)
{
	//方法分析:首先要注意前序遍历的规则,在注意规则的同时,要注意给出节点的标记位
	//1:如果当前节点的左孩子存在,则该节点的左孩子即为要查找的节点
	//2:如果给出节点的左孩子为空即leftTag=1,而且右孩子存在,则该节点的右孩子为要被查找的节点
	//3:如果给出节点的左右孩子均为空,则需要找出该节点的父节点
	//开始分析要找出父节点的情况
	//1:如果该节点是父节点的左孩子节点,而且该父节点的右孩子存在,则该节点的后继节点为兄弟节点
	//2: 应为该情况是在,给出节点没有左右孩子的情况下给出的,所以不需要在讨论为右孩子的情况
	///该情况下的情况是根节点的左子树已被完全访问,做以需要转到根节点的右子树中
	//找出根节点的右子树中第一个被访问的节点,则该节点则为要查找的节点
	if (str->leftTag == 0)
	{
		return str->leftChild;
	}
	if (str->leftTag == 1 && str->rightTag == 0)
	{
		return str->rightChild;
	}
	//以下代码是给出节点的左右孩子都不存在
	if (str->leftTag == 1 && str->rightTag == 1)
	{
		BinaryTreeNode<T>* ptr = str->parent;
		if (str == ptr->leftChild&&ptr->rightTag == 0)
		{
			return ptr->rightChild;
		}
		if (str == ptr->leftChild&&str->rightTag == 1)
		{
			bool flag = true;
			//q节点将是整个循环跳转到了根节点的右子树中,找出该右子树中第一个被访问的节点
			BinaryTreeNode<T>* q = ptr->rightChild;
			while (q != NULL)
			{
				if (q->rightTag == 0)
				{
					flag = false;
					break;
				}
			}
			if (flag == false)

			{
				return q;
			}
			else
			{
				cout << "error" << endl;
				exit(true);
			}
		}
	}
	return NULL;
}
template<typename T>
BinaryTreeNode<T>* ThreadBinaryTree<T>::PostIonderSuccessor(BinaryTreeNode<T>* str)
{
	//方法分析:
	//首先找出给定节点的父节点,开始判断
	//如果该节点是父节点的右孩子,则说明该节点在后序序列中的后序后继为父节点,即返回父节点即可
	//如果该节点不是父节点的右孩子,则按照后序遍历的规则需要找出父节点的右子树中的“最左子树”
	//即找出,在后序遍历中该节点后的第一个被访问的节点为被查找节点的后序序列中的后继,在这里要特别注意
	//该二叉树已经被线索化,所以在寻找节点是一定要注意关于标记为的状态
	BinaryTreeNode<T>* ptr = str->parent;
	if (ptr->rightChild != str)
	{
		ptr = ptr->rightChild;
		while (ptr->leftChild&&ptr->leftTag == 0)
		{
			ptr = ptr->leftChild;
		}
		return ptr;
	}
	else
		return ptr;
}
#endif
#include"ThreadBinaryTree.h"
int main(int argc, char argv[])
{
	ThreadBinaryTree<char>tree;
	tree.simulate();
	return 0;
}


展开阅读全文

二叉树中序线索化

11-26

#includernusing namespace std;rnrnstruct btNode//基类rnrn char data;rn int lflag;rn int rflag;rn btNode * lchild;rn btNode * rchild;rn//-----------------------------rnclass cthrrnrnpublic:rn btNode * bt;//根节点指针rn cthr()bt=NULL;;rn ~cthr();rn void clear(btNode * bt,int flag);rn void Delete()clear(bt,0);;///////////////////////////////////////////////////;;?????????rn void createBtree(char end);rn void create(btNode * bt,int flag, char end);//创建二叉链表rn btNode * getroot()return bt;;rn;rn//================================================================rncthr::~cthr()rnrn Delete();rn bt=NULL;rnrn//-------------------------------------------------------------------rnvoid cthr::clear(btNode *bt,int flag)rnrn if(bt&&flag!=1)rn rn clear(bt->lchild,bt->lflag);rn clear(bt->rchild,bt->rflag);rn delete bt;rn rnrn//--------------------------------------------------------------------rnvoid cthr::createBtree(char end)rnrn cout<<"按先序序列输入二叉树节点值,“#”为结束标志"<>x;rn if(x!=end)rn rn p=new btNode;rn p->data=x;rn p->lchild=NULL;rn p->rchild=NULL;rn p->lflag=0;rn p->rflag=0;rn bt=p;rn create(p,1,end);rn create(p,2,end);rn rnrn//---------------------------------------------------------rnvoid cthr::create(btNode* p, int flag, char end)rnrn btNode* q;rn char x;rn cin>>x;rn if(x!=end)rn rn q=new btNode;rn q->data=x;rn q->lchild=NULL;rn q->rchild=NULL;rn q->lflag=0;rn q->rflag=0;rn if(flag==1)p->lchild=q;rn if(flag==2)p->rchild=q;rn create(p,1,end);rn create(p,2,end);rn rnrn//--------------------------------------------------------rnclass inThreading:public cthrrnrn bool isthreaded;rnpublic:rn inThread()isThreaded=false;;rn void inThreadBtree();//生成中序线索化二叉树rn void inThread(btNode *p,btNode **h);rn void inTraThrBtree();//中序遍历线索二叉树rnrn//---------------------------------------------------------rnvoid inThreading::inThreadBtree()//生成中序线索化二叉树rnrn btNode * p, *q=NULL;rn p=bt;rn inTread(p,&q);rnrn//---------------------------------------------------------rnvoid inThreading::inThread(btNode *p,btNode **h)rnrn if(p)rn rn inTread(p->lchild,h);//访问左子树rn if((*h)!=NULL&&((*h)->rchild==NULL))rn rn (*h)->rchild=p;//h为刚被访问过的节点指针,p是当前被访问的节点指针rn (*h)->rflag=1;rn rn if(p->lchild=NULL)rn rn p->lchild=(*h);rn p->lflag=1;rn rn *h=p;rn inThread(p->rchild,h);//访问右子树rn rn isThreaed=true;rnrn//----------------------------------------------------------------------------rnvoid inThreading::inTraThrBtree()//遍历中序线索化二叉树????????????????rnrn if(isThreaded==false)rn rn cout<<"请先线索化!"<lflag==0)rn p=p->lchild;rn cout<data<<" ";rn while(p->rchild!=NULL)rn rn if(p->rflag==1)rn p=p->rchild;rn elsern rn p=p->rchild;rn while((p->lflag==0)&&(p->lchild!=NULL))rn p=p->lchild;rn rn cout<data<<" ";rn rnrn//---------------------------------------------------------rnrn1>------ Build started: Project: 中序线索化, Configuration: Debug Win32 ------rn1>Build started 2013-11-25 23:31:46.rn1>InitializeBuildStatus:rn1> Touching "Debug\中序线索化.unsuccessfulbuild".rn1>ClCompile:rn1> btreee.cpprn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(26): error C3254: 'btNode' : class contains explicit override 'dtor' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(26): error C2838: 'dtor' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(32): error C3254: 'btNode' : class contains explicit override 'clear' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(32): error C2838: 'clear' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(42): error C3254: 'btNode' : class contains explicit override 'createBtree' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(42): error C2838: 'createBtree' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(62): error C3254: 'btNode' : class contains explicit override 'create' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(62): error C2838: 'create' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(85): error C4430: missing type specifier - int assumed. Note: C++ does not support default-intrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(85): warning C4183: 'inThread': missing return type; assumed to be a member function returning 'int'rn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(91): error C2628: 'btNode::inThreading' followed by 'void' is illegal (did you forget a ';'?)rn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(92): error C3254: 'btNode' : class contains explicit override 'inThreadBtree' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(92): error C2838: 'inThreadBtree' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(99): error C3254: 'btNode' : class contains explicit override 'inThread' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(99): error C2838: 'inThread' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(120): error C3254: 'btNode' : class contains explicit override 'inTraThrBtree' but does not derive from an interface that contains the function declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(120): error C2838: 'inTraThrBtree' : illegal qualified name in member declarationrn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btreee.cpp(3): error C2059: syntax error : 'namespace'rn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btreee.cpp(3): error C2238: unexpected token(s) preceding ';'rn1>d:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btreee.cpp(50): fatal error C1075: end of file found before the left brace '' at 'd:\我的文档\visual studio 2010\projects\中序线索化\中序线索化\btree.h(5)' was matchedrn1>rn1>Build FAILED.rn1>rn1>Time Elapsed 00:00:01.57rn========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========rn求教各位大神 到底错哪了 论坛

中序线索化二叉树的问题

02-14

[code=C/C++]#includern#includernusing namespace std;rnenum PointerTagLink,Thread;rntemplaternclass TreeNodernrn private:rn TreeNode* left;rn TreeNode* right;rn public:rn T data;rn PointerTag LTag,RTag;rn TreeNode(const T& item,TreeNode* lptr,TreeNode* rptr,PointerTag LT,PointerTag RT);rn TreeNode*& Left();rn TreeNode*& Right();rnrn;rnrnTreeNode* pre;rntemplaternTreeNode::TreeNode(const T& item,TreeNode* lptr,TreeNode* rptr,PointerTag LT,PointerTag RT)rnrn data=item;rn left=lptr;rn right=rptr;rn LTag=LT;rn RTag=RT;rnrntemplaternTreeNode*& TreeNode::Left()rnrn return left;rnrntemplaternTreeNode*& TreeNode::Right()rnrn return right;rnrntemplaternTreeNode* GetTreeNode(T item,TreeNode* lptr,TreeNode* rptr,PointerTag LT,PointerTag RT)rnrn TreeNode* p=new TreeNode(item,lptr,rptr,LT,RT);rn if(p==NULL)rn rn cout<<"memory location failure"<rnvoid FreeNode(TreeNode* ptr)rnrn delete ptr;rnrntemplaternvoid InorderTree(TreeNode* t)rnrn if(t!=NULL)rn rn InorderTree(t->Left());rn cout<data;rn InorderTree(t->Right());rn rnrntemplaternvoid CountLeaf(TreeNode* t,int& count)rnrn if(t!=NULL)rn rn CountLeaf(t->Left(),count);rn CountLeaf(t->Right(),count);rn if(t->Left()==NULL && t->Right()==NULL)rn count++;rn rnrntemplaternint Depth(TreeNode* t)rnrn int left_depth=0,right_depth=0,tree_depth=0;rn if(t==NULL)rn rn return 0;rn rn elsern rn left_depth=Depth(t->Left());rn right_depth=Depth(t->Right());rn tree_depth=1+((left_depth>=right_depth)?left_depth:right_depth);rn rn return tree_depth;rnrntemplaternvoid DeleteTree(TreeNode* t)rnrn if(t!=NULL)rn rn DeleteTree(t->Left());rn DeleteTree(t->Right());rn FreeNode(t);rn rnrntemplaternvoid InThreading(TreeNode* p)rnrn if(p)rn rn InThreading(p->Left());rn if(!p->Left())rn rn p->LTag=Thread;rn p->Left()=pre;rn rn if(!pre->Right())rn rn pre->RTag=Thread;rn pre->Right()=p;rn rn pre=p;rn InThreading(p->Right());rn rn if(p==NULL)rn rn cout<<"程序内部错误"<rnvoid InOrderThreading(TreeNode* Thrt,TreeNode* t)rnrn Thrt=(TreeNode*)malloc(sizeof(TreeNode));rn if(!Thrt)rn rn cout<<"内存不足,程序关闭"<LTag=Link;rn Thrt->RTag=Thread;rn Thrt->Right()=Thrt;rn TreeNode* pre;rn if(!t)rn rn Thrt->Left()=Thrt;rn rn elsern rn Thrt->Left()=t;rn pre=Thrt;rn InThreading(t); rn pre->Right()=Thrt;rn pre->RTag=Thread;rn Thrt->Right()=pre;rn rnrntemplaternvoid InOrderTraverse_Thr(TreeNode* t)rnrn TreeNode*p=t->Left();rn while(p!=t)rn rn while(p->LTag==Link) p=p->Left();rn if(p) cout<data;rn while(p->RTag==Thread && p->Right()!=t)rn rn p=p->Right();rn cout<data;rn rn p=p->Right();rn rnrnvoid main()rnrn TreeNode* root;rn TreeNode* a_lptr=NULL,*a_rptr=NULL;rn TreeNode* b_lptr=NULL,*b_rptr=NULL;rn TreeNode* c_lptr=NULL,*c_rptr=NULL;rn TreeNode* d_lptr=NULL,*d_rptr=NULL;rn TreeNode* e_lptr=NULL,*e_rptr=NULL;rn TreeNode* p=GetTreeNode('E',e_lptr,e_rptr,Link,Link);rn TreeNode* q=GetTreeNode('D',d_lptr,d_rptr,Link,Link);rn TreeNode* r=GetTreeNode('B',b_lptr,q,Link,Link);rn TreeNode* s=GetTreeNode('C',p,c_rptr,Link,Link);rn TreeNode* t=GetTreeNode('A',r,s,Link,Link);rn root=t;rn int depth=0;rn depth=Depth(root);rn cout<* Thrt=NULL;rn InOrderThreading(Thrt,root);rn //InOrderTraverse_Thr(root);rn DeleteTree(root);rnrnrn[/code]rnrn我的目的是中序线索化一棵二叉树,但是有点错误,请大家帮我看看rnrn涉及函数如下:rnvoid InOrderThreading(TreeNode* Thrt,TreeNode* t)rnvoid InThreading(TreeNode* p)rn 论坛

没有更多推荐了,返回首页