java编写非递归与递归创建有序的二叉树
Posted 小牛儿帥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java编写非递归与递归创建有序的二叉树相关的知识,希望对你有一定的参考价值。
java非递归与非递归创建有序的二叉树
二叉树
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分 。
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点
二叉树是数据结构中的线性存储的结构,那什么叫有序的二叉树呢?不然就是在存储数据的时候是按照数据大小进行存储,在java语言中也存在此结构的类ThreeSet类,它是一个容器,用来存放数据且其中不能存放相同元素,因为.二叉树认为能够存放在树形结构中的元素都是有序元素。例如定义一组数据{7,2,8,1,4,3,5},在树形结构中如下图所示。
二叉树的遍历过程中有三种方式,分别是先序、中序和后序,通常情况下要熟悉三种遍历的方式。一般中序输出是有顺序的,从小到大或者从大到小。
现在我们需要构建一颗普通二叉树(不具有顺序)
二叉树的创建
二叉树实则是一颗倒立着的树,拥有结点、左右子结点,所以构建二叉树的结构具有很多方式,而二叉树的样式也有很多,接下来重点介绍三种不同方式创建二叉树,分别是普通无序二叉树,有序递归和有序非递归创建二叉树。
二叉树的成员变量
构建基本的成员变量
public class Node {//构建一个二叉树结点类
public Node leftNode;//左节点
public Node rightNode;//右节点
public int data;//结点里存放的数据
public Node root;//根节点
public List<Node>datas;//构建结点的集合
public Node() {//无参的构造方法
}
public Node(Node leftNode,Node rightNode,int date) {//初始化一个结点
this.leftNode=leftNode;
this.rightNode=rightNode;
this.date=date;
}
public Node(int date) {//初始化只包含一个数据的结点
this(null,null,date);
}
}
接下来构建普通的二叉树方法(非递归)
public void createNode(int[] arr){
datas = new ArrayList<Node>();
for(int i:arr){
datas.add(new Node(i));
}
root = datas.get(0);//初始化根节点
for(int i=0;i<arr.length;i++){
datas.get(i).leftNode=datas.get(2*i+1);//建立左节点
if(2*i+2<arr.length){//防止下标越界
datas.get(i).rightNode = datas.get(2*i+2);//建立右节点
}
}
}
递归创建普通二叉树
public void createNodeN(Node n,int i){//平衡二叉树
if(leftNode==null&&rightNode!=null){
leftNode=node;
}else if(leftNode!=null&&rightNode==null){
rightNode=node;
}else if(leftNode==null&&rightNode==null){
leftNode=node;
}else{
if(i%2==0)
leftNode.createNode(node,i++);
esle
rightNode.createNode(node,i++);
}
}
构建有序的二叉树(递归创建)
第一种方式
public void createNodeRecursive(int[] arr,int index){//根结点调用此方法,默认根节点存在,index数组下标,从1开始
if(index>arr.length){//边界条件
return;
}
if(arr[index]<data){//如果当前结点的数据大于将排序的结点
if(leftNode==null){//当前this结点的左节点为空
leftNode = new Node(arr[index++]);
}else{//寻找下一个空结点
leftNode.createNodeRecusive(arr,index);
}
}else{//当前this结点小于排序结点
if(rightNode==null){//右节点为空,直接将排序结点赋值给右节点
rightNode = new Node(arr[index++]);
}else{
rightNode.createNodeRecursive(arr,index);
}
}
}
第二种方式(同样也是递归)
public void createNodeRecursive(Node node){//参数列表不同,方法的重载
if(node.data<data){
if(leftNode==null){
leftNode=node;
}else{
leftNode.createNodeRecursive(node);
}
}else{
if(rightNode==null){
rightNode=node;
}else{
rightNode.createNodeRecursive(node);
}
}
有序非递归创建二叉树
思路:我们是将LIst集合中的根节点之后的结点与创建中的二叉树结点进行比较,比他小放左边大放右边,循环的调件就是二叉树中存在左右节点,循环往下遍历。
/*
* 思路 循环判断比较,从根节点开始,如果结点存在左右子节点是执行while循环,否则退出
* 如果刚好左节点为空此时的值刚好小于根节点的值 直接将该节点赋到左节点并退出循环
* 相反如果该值大于右节点此时右节点刚好为空 将该节点赋到右节点
* 如果左节点不为空右节点为空,此时值刚好又小于结点值,所有就要往下遍历
* 如果该右节点不为空左节点为空,此时值刚好又大于结点值,所有继续往下遍历
* 如果作用结点都不为空,则要判断该值是否大于该结点值,判断位置
*/
public void createNode(int[] arr){
dates= new ArrayList<Node>();//初始化集合
for(int i=0:arr){//将arr包装进到ArrayList集合当中
datas.add(new Node(i));
}
root = datas.get(0);//初始化根节点
for(int i=1;i<arr.length;i++){//除根结之外的其他节点的排序比较创建
Node node = root;//每次的子结点从root结点开始遍历
while(node.leftNode!=null||node.rightNode!=null&&datas.indexOf(node)<arr.length-1){//二叉树最坏的一种情况(只存在左子树或者右子树)的结点树
//如果左右结点不为空,列举除包含的所有情况
if(datas.get(i)<node.data&&node.leftNode==null){
node.leftNode=datas.get(i);
break;
}else if(node.data<datas.get(i).data&&node.rightNode==null){
node.rightNode = datas.get(i);
break;
}else if(node.rightNode!=null&&node.leftNode==null){//不为空子结点后移
node = node.rightNode;
}else if(node.leftNode!=null&&node.rightNode==null){
node = node.leftNode;
}else if(node.leftNOde!=null&&node.rightNode!=null){//都不为空时需要判断,如果小于该节点则往左遍历,控制遍历方向
if(datas.get(i).data<node.data){
node = node.leftNode;
}else{
node = node.rightNode;
}
}
}//左右结点都为空
if(datas.get(i)<node.data){
node.leftNode=datas.get(i);
}else{
node.rightNOde=datas.get(i);
}
}
}
中序遍历
public void inorder(Node root){
if(root!=null){
inorder(root.leftNode);
System.out.print(root.data);
inorder(root.rightNode);
}
}
遍历结果
package node;
public class Test {
public static void main(String[] args) {
// TODO 自动生成的方法存根
int[] arr= {7,2,8,1,4,3,5};
Node node = new Node();
node.createOrder(arr);
node.inorder(node.root);
}
}
结果:
以上是关于java编写非递归与递归创建有序的二叉树的主要内容,如果未能解决你的问题,请参考以下文章