`

大话数据结构十五:线索二叉树

 
阅读更多

1. 什么是线索二叉树?

n个结点的二叉链表中含有(2n-(n-1)=n+1个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前驱和后继结点的指针

(这种附加的指针称为"线索")。这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。


2. 为什么要加线索?

① 很多空指针域没有存储任何事物,对内存资源是一种浪费。

② 二叉链表中,我们只能知道每个结点指向其左右孩子结点的地址,却不知道每个结点的前驱是谁,后继是谁。

线索链表解决了无法直接找到该结点在某种遍历序列中的前驱和后继结点的问题。

④ 线索二叉树等于把一棵二叉树转变成了一个双向链表,这样我们插入删除某个结点将非常方便。


3. 什么是线索化?

对二叉树以某种次序遍历使其变成线索二叉树的过程称为线索化,线索化的过程就是在遍历过程中修改空指针的过程。


4. 线索二叉树的结构:

leftChild
isLeftTag
data
isRightTag
rightChild

isLeftTag为0时leftChild指向该结点的左孩子,为1时leftChild指向该结点的前驱;

isRightTag为0时rightChild指向该结点的右孩子,为1时rightChild指向该结点的后继;


注意:isLeftTag,isRightTag只是存放0或1数字的布尔型变量,isLeftTag用于区分leftChild指向左孩子还是前驱,

isRightTag用于区分rightChild指向右孩子还是后继,其占用的内存空间要小于像leftChild和rightChild这样的指针变量。


5. Java实现线索二叉树:

public class ThreadTree {
	private Node root;// 根节点
	private Node preNode;// 线索化的时候保存前驱

	/**
	 * 内部节点类
	 */
	private class Node {
		private int data;
		private Node leftChild; // 左孩子节点
		private Node rightChild; // 右孩子节点
		private boolean isLeftTag; // 左孩子标志域
		private boolean isRightTag; // 右孩子标志域

		public Node(int data) {
			this.data = data;
			this.leftChild = null;
			this.rightChild = null;
			this.isLeftTag = false; // leftTag为0时指向该结点的左孩子,为1时指向该结点的前驱
			this.isRightTag = false; // rightTag为0时指向该结点的右孩子,为1时指向该结点的后继
		}
	}

	public ThreadTree() {
		this.root = null;
		this.preNode = null;
	}

	/**
	 * 递归创建二叉树
	 * 
	 * @param node
	 * @param data
	 */
	public void buildTree(Node node, int data) {
		if (root == null) {
			root = new Node(data);
		} else {
			if (data < node.data) {
				if (node.leftChild == null) {
					node.leftChild = new Node(data);
				} else {
					buildTree(node.leftChild, data); // 递归遍历左子树
				}
			} else {
				if (node.rightChild == null) {
					node.rightChild = new Node(data);
				} else {
					buildTree(node.rightChild, data); // 递归遍历右子树
				}
			}
		}
	}

	/**
	 * 中序遍历将二叉树线索化
	 * 
	 * @param node
	 */
	public void inThreading(Node node) {
		if (node != null) {
			inThreading(node.leftChild); // 线索化左子树(递归)
			if (node.leftChild == null) { // 没有左孩子
				node.isLeftTag = true; // 前驱线索
				node.leftChild = preNode; // 左孩子指针指向前驱
			}
			if (preNode != null && preNode.rightChild == null) { // 前驱没有右孩子
				preNode.isRightTag = true; // 后继线索
				preNode.rightChild = node; // 前驱右孩子指针指向后继
			}
			preNode = node;
			inThreading(node.rightChild); // 线索化右子树(递归)
		}
	}

	/**
	 * 中序遍历线索二叉树
	 * 
	 * @param node
	 */
	public void inOrderThread(Node node) {
		if (node != null) {
			while (node != null && !node.isLeftTag) { // 如果左孩子不是线索
				node = node.leftChild;
			}

			do {
				System.out.print(" " + node.data + " ");
				if (node.isRightTag) { // 如果右孩子是线索
					node = node.rightChild;
				} else { // 有右孩子
					node = node.rightChild;
					while (node != null && !node.isLeftTag) {
						node = node.leftChild;
					}
				}
			} while (node != null);
		}
	}
	
	/**
	 * 测试类
	 * @param args
	 */
	public static void main(String[] args) {
		int[] arr = { 6, 4, 8, 1, 7, 3, 9, 2, 5 };
		ThreadTree threadTree = new ThreadTree();
		for (int i = 0; i < arr.length; i++) {
			threadTree.buildTree(threadTree.root, arr[i]); // 构建一棵二叉树
		}
		threadTree.inThreading(threadTree.root);// 采用中序遍历将二叉树线索化
		threadTree.inOrderThread(threadTree.root);// 中序遍历线索二叉树
	}
}







分享到:
评论

相关推荐

    C++(数据结构):树和二叉树

    C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树和二叉树 C++(数据结构):树...

    线索二叉树(数据结构课设)

    在数据结构课设中,线索二叉树是一个常见的项目,可以帮助学生深入理解非递归遍历的原理。提供的“线索二叉树”文件可能包含了实现线索二叉树的C++代码,包括节点定义、插入、删除、遍历等操作。这样的代码实例对于...

    线索二叉树的数据结构课程设计

    线索二叉树是一种在二叉树中添加线索(thread)以方便进行遍历的数据结构,主要应用于不支持随机访问的存储系统中。这种数据结构在实际应用中,尤其是在需要高效遍历二叉树(如前序、中序、后序遍历)时,能提供便利...

    数据结构5.10二叉树线索链表存储结构

    ### 数据结构5.10二叉树线索链表存储结构 #### 一、知识点概述 在数据结构的学习中,二叉树是一种非常重要的非线性数据结构,它具有丰富的应用场景和变化形式。其中,二叉树的线索链表存储结构是通过对二叉树的...

    数据结构课程设计线索二叉树

    1. 定义线索二叉树节点结构,包含数据域、左右孩子指针以及前驱和后继线索。 2. 实现插入、删除节点的功能,同时更新线索信息。 3. 设计前序、中序、后序线索二叉树遍历算法。 4. 编写测试用例,验证各种操作的正确...

    数据结构课程设计 线索二叉树

    总的来说,线索二叉树是二叉树数据结构的一种优化,通过添加线索信息,使得在中序遍历、前序遍历和后序遍历时可以更加高效地访问节点。这对于需要频繁进行遍历操作的场景非常有用,例如在某些搜索和排序算法中。

    合肥工业大学数据结构试验四线索二叉树

    线索二叉树是数据结构中一种特殊类型的二叉树,尤其在查找和遍历方面具有优势,特别是在实现二叉搜索树的迭代操作时。这种数据结构主要用于改进二叉树的中序遍历性能,使得在非递归情况下也能轻松找到前驱和后继节点...

    数据结构 线索二叉树

    - 后序遍历:后序遍历相对复杂,需要借助辅助数据结构(如栈),线索二叉树在此方面并无明显优势。 3. **线索二叉树的应用**: - 非递归遍历:线索二叉树的最大优势在于提供了一种非递归遍历二叉树的方法,避免了...

    数据结构线索二叉树严蔚敏

    在众多的数据结构类型中,线索二叉树是一种特殊形式的二叉搜索树,主要用于提高对二叉树的遍历效率,特别是对于查找前驱和后继节点。这个主题与严蔚敏教授的教材《数据结构》紧密相关,这是一本在中国计算机科学教育...

    数据结构 线索二叉树 严蔚敏

    线索二叉树作为一种高效的数据结构,其概念由著名计算机科学家严蔚敏教授提出,它对传统的二叉树进行了改良,通过增加线索来提升遍历效率,尤其在需要频繁遍历操作的场景下表现突出。 线索二叉树是在二叉树的基础上...

    数据结构第五章-树与二叉树-C语言实现线索二叉树

    【数据结构】第五章——树与二叉树——C语言实现线索二叉树 资源内包含7个文件: - 3个头文件 - BiTree.h ——二叉树头文件,用于对二叉树的数据结构的定义、实现算法的声明 - ThreadTree.h —— 线索二叉树头文件...

    数据结构实验十:树及二叉树的应用试验

    数据结构实验十主要关注的是树和二叉树的应用,特别是如何判断一棵二叉树是否为二叉排序树。二叉排序树(Binary Search Tree,BST)是一种特殊的二叉树,其特性是左子树上所有节点的值均小于根节点的值,而右子树上...

    数据结构课程设计:建立二叉树并求指定结点路径

    在数据结构的学习中,二叉树是一种非常基础且重要的数据结构。本次课程设计的主题是“建立二叉树并求指定结点路径”,这涉及到对二叉树的理解、创建、遍历以及路径查找等多个核心概念。 首先,二叉树是树形数据结构...

    线索二叉树的建立、删除、插入、恢复线索

    五、线索二叉树的应用 线索二叉树有很多实际应用,例如: * 数据库索引 * 文件系统索引 * 编译器中的符号表管理 六、线索二叉树的优点和缺点 线索二叉树的优点: * 可以快速地访问和遍历二叉树 * 可以快速地...

    数据结构--二叉树--思维导图.pdf

    "数据结构--二叉树--思维导图" 二叉树是一种常见的数据结构,它是一种树形结构,每个节点最多有两个孩子节点,分别是左子树和右子树。二叉树可以用来存储大量数据,并且可以快速地查找、插入和删除数据。 二叉树的...

    数据结构实验三:-二叉树的操作.docx

    深刻理解二叉树性质和及各种存储结构的特点及适用范围;掌握用指针类型描述、访问和处理二叉树的运算;熟练掌握二叉树的遍历算法;在遍历算法的基础上设计二叉树更复杂操作算法;认识哈夫曼树、哈夫曼编码的作用和...

    线索二叉树运算的课程设计

    线索二叉树是一种特殊的二叉树数据结构,它通过在二叉链表的空指针域中存储指向结点在特定遍历顺序下的前驱和后继结点的指针,从而方便快速的遍历。在本课程设计中,重点在于实现中序线索二叉树的建立、插入、删除...

    线索二叉树 算法 建立 输出等。。。

    构建线索二叉树: 1. 初始化:在构建线索二叉树之前,首先需要对原始二叉树进行遍历,并为每个节点分配两个线索指针,初始化为空。 2. 中序遍历构建:从根节点开始,按照中序遍历的顺序访问每个节点。在遍历过程中,...

    数据结构之线索二叉树详细解释

    线索二叉树是一种在二叉树中添加额外线索来辅助遍历的数据结构,它使得在二叉树中实现前序、中序和后序遍历变得更加高效。在标准的二叉链表表示中,我们只能通过左右孩子指针进行遍历,而线索二叉树通过在节点中增加...

Global site tag (gtag.js) - Google Analytics