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

原创 2015年11月20日 13:00:08

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

#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;
}


找出二叉查找树中指定结点的”下一个"结点(也即中序后继)

设计一个算法,找出二叉查找树中指定结点的“下一个“结点(也即中序后继)。可以假定每个结点都含有指向父结点的连接。 下面是该算法的实现代码(已正确处理结点为空的情况) public Tree...
  • wangfengfan1
  • wangfengfan1
  • 2015年08月22日 21:28
  • 1379

求一棵二叉树中任意节点的后继节点(后继节点是指在中序遍历中紧随其后的节点)

问题定义:         RT,基本上标题已经说得很清楚了。Write an algorithm to find the 'next' node (eg. in-order successor) ...
  • lalor
  • lalor
  • 2012年05月31日 20:16
  • 7492

剑指offer-----输出二叉树的后继节点(java版)

一 题目 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 二 例子 对于下面的二叉树,8的后继...
  • sniperken
  • sniperken
  • 2016年12月26日 21:27
  • 446

二叉树的线索化及其前驱后继查找

一 实质 遍历二叉树过程中用线索(前驱和后继)取代
  • XSF50717
  • XSF50717
  • 2014年10月15日 10:33
  • 2911

二叉树  前序 后继  怎么理解

进来学习二叉树,在插入删除时对二叉树的前序后继,自我感觉有点绕,让人摸不着头脑,百度后,竟没有发现一篇讲解怎么理解二叉树的前序与后继,于是自己研究起来。 1.二叉树前序与后继的一个判...
  • u011317784
  • u011317784
  • 2014年10月19日 19:54
  • 1095

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

二叉树线索化以及线索化的先序、中序、后序遍历 有详细的图解 和 程序代码 解读,以及 为什么要线索化二叉树...
  • My_heart_
  • My_heart_
  • 2016年08月01日 18:04
  • 16341

二叉树遍历的前驱和后继规则说明

二叉树遍历的递归算法和非递归算法我们当然应该很熟悉了,不过还有另外一种遍 历方式,就是增加了树的构造,然后不允许递归或是用到栈进行遍历,如线索树或者是 有父母节点的二叉树等等等等。这样的遍历就需要我们...
  • xiaokang06
  • xiaokang06
  • 2014年03月25日 19:51
  • 4379

数据结构例程——线索化二叉树(中序)

本文是数据结构基础系列(6):树和二叉树中第14课时线索二叉树的例程。#include #include #define MaxSize 100 typedef char ElemType; typ...
  • sxhelijian
  • sxhelijian
  • 2015年10月20日 05:36
  • 4566

二叉树的后继结点

题目:给定一个二叉树上的结点,输出其后继结点(按中序遍历)
  • woshi750814343
  • woshi750814343
  • 2014年04月16日 11:26
  • 1207

数据结构二叉树之通过前序和中序恢复二叉树后续方法输出

#include"stdio.h" #include"stdlib.h" #define max 100 typedef struct node { char data; struct node ...
  • Yiyuan_chen
  • Yiyuan_chen
  • 2016年11月10日 00:02
  • 819
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:给出二叉树,将二叉树进行中序线索化,在根据中序线索化二叉树,找出给定节点的前序后继节点,和给出节点的后序后继节点
举报原因:
原因补充:

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