IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++线索二叉树的相关操作 -> 正文阅读

[C++知识库]C++线索二叉树的相关操作

?

C++线索二叉树的相关操作

#pragma once
//5.21 --212--线索二叉树的类定义
template<class T>
struct ThreadNode
{
	int ltag, rtag;
	ThreadNode<T>* leftChild, * righChild;
	T data;
	ThreadNode(const T item) :data(item), leftChild(nullptr), righChild(nullptr),
		ltag(0), rtag(0) {}

};
template<class T>
class ThreadTree {
protected:
	ThreadNode<T>* root;
	void createInThread(ThreadNode<T>* current, ThreadNode<T>*& pre);
	//中序遍历建立二叉树
	ThreadNode<T>* parent(ThreadNode<T>* t);
	//寻找结点t的父结点
public:
	ThreadTree() :root(nullptr) {}
	void createInThread();
	ThreadNode<T>* First(ThreadNode<T>* current);//寻找第一个结点
	ThreadNode<T>* Last(ThreadNode<T>* current);//寻找最后一个结点
	ThreadNode<T>* Next(ThreadNode<T>* current);//寻找  后继结点
	ThreadNode<T>* Prior(ThreadNode<T>* current);//寻找  前驱结点
	void InOrder(void (*visit)(ThreadNode<T>* p));
	void PreOrder(void (*visit)(ThreadNode<T>* p));
	void PostOrder(void (*visit)(ThreadNode<T>* p));
	
	void InsertRight(ThreadNode<T>* current);//插入一个结点

	//........
};
//5.22 --213-中序二叉树 成员函数实现
//求序列的 第一个结点
template<class T>
ThreadNode<T>* ThreadTree<T>::First(ThreadNode<T>* current) {
	//以*current為根的 第一个结点
	ThreadNode<T>* p = current;
	while (p->ltag == 0) {//只要有 左子女,就一直向左
		p = p->leftChild;//最左下结点,(不一定是叶子结点)
	}
	//最左边的就是 中序遍历的第一个结点。
	return p;
};
//求后继
template<class T>
ThreadNode<T>* ThreadTree<T>::Next(ThreadNode<T>* current) {
	ThreadNode<T>* p = current->righChild;
	if (current->rtag == 0) {//该点 A有 右子女,
		return First(p);//求该点的右子女为根的子树的 第一个结点就是E
	}else{//否则就是 rtag==1.存放的就是后继结点。
		return p;//返回后继结点
	}
};
//序列的最后一个结点
template<class T>
ThreadNode<T>* ThreadTree<T>::Last(ThreadNode<T>* current) {
	ThreadNode<T>* p = current;
	while (p->rtag == 0) {//只要有右子女,就一直向右。
		p = p->righChild;
	}
	return p;
};
//求 前驱结点。
template<class T>
ThreadNode<T>* ThreadTree<T>::Prior(ThreadNode<T>* current) {
	ThreadNode<T>* p = current->leftChild;//先记录改点的左子女,
	if (current->ltag == 0) {//如果 有左 子女,比如A,
		return Last(p);//求以 该点 左子女为根的子树(比如B) 的最右一个结点。
	}
	else {//否则就是rtag==1,存放的就是 前驱结点
		return p;
	}
};
//5.23进行中序遍历
template<class T>
void ThreadTree<T>::InOrder(void (*visit)(ThreadNode<T>* p)) {
	ThreadNode<T>* p;
	for (p = First(root);p != nullptr;p = Next(p)) {
		visit(p);
	}
};
//5.24利用中序遍历 对二叉树进行中序线索化
template<class T>
void ThreadTree<T>::createInThread() {
	ThreadNode<T>* pre = nullptr;//前驱结点指针
	if (root != nullptr) {//非空二叉树,进行线索化
		createInThread(root, pre);//中序遍历 线索化
		pre->righChild = nullptr;//后 处理中序最后一个结点指针。(最后一个是特殊的)
		pre->rtag = 1;
	}
};
template<class T>
void ThreadTree<T>::createInThread(ThreadNode<T>* current,
	ThreadNode<T>*& pre) {
	//通过中序遍历,对二叉树进行线索化
	if (current == nullptr) {
		return;
	}
	createInThread(current->leftChild, pre);//递归,左子树线索化
	if (current->leftChild == nullptr) {//建立当前结点的前驱
		current->leftChild = pre;
		current->ltag = 1;
	}
	if (pre != nullptr && pre->righChild == nullptr) {
		pre->righChild = current;//建立当前结点的后继
		pre->rtag = 1;
	}
	pre = current;
	createInThread(current->righChild, pre);//递归,右子树线索化
};

//5.25 在中序遍历二叉树上实现前序遍历算法
template<class T>
void ThreadTree<T>::PreOrder(void (*visit)(ThreadNode<T>* current)) {
	ThreadNode<T>* current = root;
	while (current != null) {
		visit(current);//访问根结点
		if (current->ltag == 0) {//如果有 左子女.即为 后继
			current = current->leftChild;
		}
		else if (current->rtag == 0) {//否则 有 右子女,即为后继
			current = current->righChild;
		}
		else {
			//沿着后继继续检测
			while (current != nullptr && current->rtag == 1) {
				current = current->righChild;//直到有 右子女的结点
			}
			if (current != nullptr) {//右 子女 即为后继
				current = current->righChild;
			}
		}
	}
};
//5.26 在中序遍历二叉树上实现后序遍历算法
template<class T>
void ThreadTree<T>::PostOrder(void (*visit)(ThreadNode<T>* current)) {
	ThreadNode<T>* current = root;
	//寻找最后一个结点
	while (current->ltag == 0 || current->rtag == 0) {
		if (current->ltag == 0) {
			current = current->leftChild;
		}
		else if (current->rtag == 0) {
			current = current->righChild;
		}
	}
	visit(current);//访问第一个结点
	ThreadNode<T>* p;
	while ((p = parent(t)) != nullptr) {
		if (p->righChild == current || p->rtag == 1) {//*current是*p的后序后继
			current = p;
		}else{//否则,current 移动到 p的右子树
			current = p->righChild;
			while (current->ltag == 0 || current->rtag == 0) {
				if (current->ltag == 0) {
					current = current->leftChild;
				}
				else if (current->rtag == 0) {
					current = current->righChild;
				}
			}
		}
		visit(current);
	}
};
//5.27 求父结点
template<class T>
ThreadNode<T>* ThreadTree<T>::parent(ThreadNode<T>* t) {
	ThreadNode<T>* p;
	if (t == root)return nullptr;//根结点 无父结点
	for (p = t;p->ltag == 0;p = p->leftChild);//求 t为根子树第一个结点。
	if (p->leftChild != nullptr)
		for (p = p->leftChild;
			p != nullptr && p->leftChild != t && p->righChild != t;
			p = p->righChild);
	if (p == nullptr || p->leftChild == nullptr) {
		for (p = t;p->rtag == 0;p = p->righChild);
		for (p = p->righChild;p != nullptr && p->leftChild != t && p->righChild != t;
			p = p->leftChild);
	}
	return p;
};
//5.28
template<class T>
void ThreadTree<T>::InsertRight(ThreadNode<T>* s, ThreadNode<T>* r) {
	//将新结点*r当做*s的 右子女插入
	r->rightChild = s->rightChild;//s的右子女或者后继 线索 传给r
	r->rtag = s->rtag;//后继线索 标志一同传送
	t->leftChild = s;
	r->ltag = 1;
	s->rightChild = r;//r成为s右子女
	s->rtag = 0;
	if (r->rtag == 0) {//s原来有右子女
		ThreadNode<T>* temp;
		temp = First(r->rightChild);//在s原来的柚子树找中序遍历 第一个点
		temp->leftChild = r;//建立指向r的前驱线索
	}

};
//在*s的左子女处插入 *p
template<class T>

void ThreadTree<T>::InsertRight(ThreadNode<T>* s, ThreadNode<T>* p) {

	if (s != nullptr && p != nullptr) {
		if (s->rtag) {//首先判断 是否有子女。  无!
			p->leftChild = s->leftChild;//s的左线索 复制给 p
			p->rtag = 1;      //p无右子女
		}
		else {//有左子女
			p->leftChild = s->leftChild;
			p->ltag = 0;//插入
			p->rightChild = s;//p的后继 是s
			p->rtag = 1;//p无右子女

			ThreadNode<T>* temp = p->leftChild;
			while (!temp->rtag) {//找p左子树 中序遍历中的最后一个点。
				temp = temp->rightChild;
			}
			temp->rightChild = p;//该点的后继 是 p

		}
		s->leftChild = p;
		s->ltag = 0;
	}
};

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 11:51:13  更:2021-12-07 11:53:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:07:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码