Java数据结构与算法

本文介绍了如何使用Java实现顺序存储二叉树和线索化二叉树。详细讲解了顺序存储二叉树的概念、要求、特点以及代码实现,接着探讨了线索化二叉树的问题分析、基本介绍、应用案例,包括中序线索二叉树的建立和遍历。
摘要由CSDN通过智能技术生成

目录

顺序存储二叉树

概念

基本说明

要求

特点

代码实现

应用实例

线索化二叉树

 问题分析

基本介绍

应用案例

思路分析

代码实现

运行效果

 遍历线索化二叉树

代码实现

完整代码

运行效果


顺序存储二叉树

概念

基本说明

从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组,看右面的示意图。

要求

1)右图的二叉树的结点,要求以数组的方式来存放arr:[1,2,3,4,5,6,6]

2)要求在遍历数组arr时,仍然可以以前序遍历中序遍历后序遍历的方式完成结点的遍历。

特点

1)顺序二叉树通常只考虑完全二叉树

2)第n个元素的左子节点为2*n+1

3)第n个元素的右子节点为2*n+2

4)第n个元素的父节点为(n-1)/2

5)n:表示二叉树中的第几个元素(按0开始编号如图所示)

代码实现

package tree;

public class ArrBinaryTreeDemo {

	public static void main(String[] args) {
		int[] arr= {1,2,3,4,5,6,7};
		//创建一个ArrBinaryTree
		ArrBinaryTree arrBinaryTree=new ArrBinaryTree(arr);
		arrBinaryTree.preOrder();//1,2,4,5,3,6,7
	}
}
//编写一个ArrayBinaryTree,实现顺序存储二叉树遍历
class ArrBinaryTree{
	private int[] arr;//存储数据结点的数组
	
	public ArrBinaryTree(int[] arr) {
		this.arr=arr;
	}
	
	//重载preOrder
	public void preOrder() {
		this.preOrder(0);
	}
	//编写一个方法,完成顺序存储二叉树的前序遍历
	/*index 属性的下标*/
	public void preOrder(int index) {
		//如果数组为空,或者arr.length=0
		if (arr==null||arr.length==0) {
			if (arr==null||arr.length==0) {
				System.out.println("数组为空,不能按照二叉树的前序遍历");
			}
			//输出当前这个元素
			System.out.println(arr[index]);
			//向左递归遍历
			if ((index*2+1)<arr.length) {
				preOrder(2*index+1);
			}
			//向右递归遍历
			if((index*2+2)<arr.length) {
				preOrder(2*index+2);
			}			
		}
	}
}

 运行结果为:1,2,4,5,3,6,7

应用实例

八大排序算法中的堆排序,就会使用到顺序存储二叉树。

线索化二叉树

将数列{1,3,6,8,10,14}构建成一棵二叉树

 问题分析

1)当我们对上面的二叉树进行中序遍历时,数列为{8,3,10,1,6,14}

2)但是6,8,10,14这几个节点的左右指针,并没有完全的利用上

3)如果我们希望充分的利用各个节点的左右指针,让各个节点可以指向自己前后节点,怎么办?

4)解决方案:线索二叉树

基本介绍

1)nge结点的二叉链表中含有n+1【公式2n-(n-1)=n+1】个空指针域。利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")

2)这种加上了线索的二叉树表称为线索链表,相应的二叉树称为线索二叉树。根据线索性质的不同,线索二叉树可分为前序线索二叉树中序线索二叉树后序线索二叉树三种。

3)一个结点的前一个结点,称为前驱结点

4)一个结点的后一个结点,称为后继结点

应用案例

说明:将下面的二叉树,进行中序线索二叉树。中序遍历的数列为{8,3,10,1,14,6}

思路分析

 中序遍历的结果:{8,3,10,1,14,6}

 说明:当线索化二叉树后,Node节点的属性left和right,有如下情况

1)left指向的是左子树,也可能是指向的前驱节点,比如①节点left指向的左子树,而⑩节点的left指向的就是前驱节点。

2)right指向的是右子树,也可能是指向后继节点,比如①节点right指向的是右子树,而⑩节点的right指向的是后继节点。

代码实现

package threadedbinarytree;

public class ThreadedBinaryTreeDemo {

	public static void main(String[] args) {
		//测试一把中序线索二叉树的功能
		HeroNode root=new HeroNode(1,"tom");
		HeroNode node2=new HeroNode(3,"jack");
		HeroNode node3=new HeroNode(6,"smith");
		HeroNode node4=new HeroNode(8,"mary");
		HeroNode node5=new HeroNode(10,"king");
		HeroNode node6=new HeroNode(14,"dim");
		
		//二叉树,后面我们要递归创建,现在简单处理使用手动创建
		root.setLeft(node2);
		root.setRight(node3);
		node2.setRight(node4);
		node2.setRight(node5);	
		node3.setLeft(node6);
		
		//测试线索化
		ThreadedBinaryTree threadedBinaryTree=new ThreadedBinaryTree();
		threadedBinaryTree.setRoot(root);
		threadedBinaryTree.threadedNodes();
		
		//测试:以10号结点测试
		HeroNode leftNode=node5.getLeft();
		HeroNode rightNode=node5.getRight();
		System.out.println("10号结点的前驱结点是="+leftNode);//3
		System.out.println("10号结点的后继结点是="+rightNode);//1
	}
}
定义ThreadBinaryTree实现了线索化功能的二叉树
class ThreadedBinaryTree{
	private HeroNode root;
	
	//为了实现线索化,需要创建要给指向当前结点的前驱结点的指针
	//在递归进行线索化时,pre总是保留前一个结点
	private HeroNode pre&#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值