二叉树的构造

简介:

二叉树是很常用的一种数据结构。但是在使用它之前,得先构造一棵二叉树,下面这篇文章记录一下如何构造一棵二叉排序树 和 完全二叉树。

 

一,给定一组整数,请构造一棵二叉排序树

比如:2,4,5,1,3

构造二叉排序树,采用了递归方式来构造。

复制代码
 1     //根据数组 arr 中的元素构造一棵二叉排序树
 2     public void buildTree(int[] arr){
 3         for (int node : arr) {
 4             insert(node);
 5         }
 6     }
 7     
 8     private void insert(int ele){
 9         root =  insert(root, ele);
10     }
11     
12     private BinaryNode insert(BinaryNode root, int ele){
13         //递归的结束条件.base condition
14         if(root == null)
15             return new BinaryNode(ele);
16         
17         if(root.ele > ele)
18             root.left = insert(root.left, ele);
19         else if(root.ele < ele)
20             root.right = insert(root.right, ele);
21         else
22             root.left = insert(root.left, ele);
23         
24         return root;//若某结点的左右孩子不空,在后续的递归调用中该结点的左右指针是不会变的.
25     }
复制代码

 

二,给定一组整数,请按照从上到下,从左到右的顺序构造一棵二叉树(其实就是完全二叉树)

比如:2,4,5,1,3

构造一棵完全二叉树,其实这个过程与“二叉树的按层打印非常相似”。因此,需要一个队列保存“下一个待构造的结点”。

当某个结点的左右孩子都已经构造完毕时(next==2),从队列中取出下一个结点,并开始构造它的左右孩子。

复制代码
 1     public void buildCompleteTree(int[] nodes){
 2         Queue<BinaryNode> queue = new LinkedList<BinaryNode>();
 3         root = new BinaryNode(nodes[0]);
 4         BinaryNode currentNode = null;
 5         
 6 //        queue.offer(root);
 7         int next = 0;//标记当前结点的左右孩子是否已经构造完毕,当next为2时表示当前结点的左右孩子已经构造完毕
 8         currentNode = root;//保存当前正在"构造"的结点
 9         int count = 1;//记录数组中的已经构造的元素
10         while(count < nodes.length){
11             if(next == 2)//某结点的左右孩子已经构造好了
12             {
13                 currentNode = queue.poll();
14                 next = 0;
15             }
16             if(currentNode.left == null && count < nodes.length)
17             {
18                 currentNode.left = new BinaryNode(nodes[count++]);
19                 queue.offer(currentNode.left);
20                 next++;
21             }
22             if(currentNode.right == null && count < nodes.length)
23             {
24                 currentNode.right = new BinaryNode(nodes[count++]);
25                 queue.offer(currentNode.right);
26                 next++;
27             }
28         }    
29     }
复制代码

 

三,完整代码实现

import java.util.LinkedList;
import java.util.Queue;

public class MyBinarySearchTree {

    private class BinaryNode{
        BinaryNode left;
        BinaryNode right;
        int ele;
        public BinaryNode(int ele) {
            this.ele = ele;
        }
    }
    
    private BinaryNode root;//根节点
    
    //根据数组 arr 中的元素构造一棵二叉排序树
    public void buildTree(int[] arr){
        for (int node : arr) {
            insert(node);
        }
    }
    
    private void insert(int ele){
        root =  insert(root, ele);
    }
    
    private BinaryNode insert(BinaryNode root, int ele){
        //递归的结束条件.base condition
        if(root == null)
            return new BinaryNode(ele);
        
        if(root.ele > ele)
            root.left = insert(root.left, ele);
        else if(root.ele < ele)
            root.right = insert(root.right, ele);
        else
            root.left = insert(root.left, ele);
        
        return root;//若某结点的左右孩子不空,在后续的递归调用中该结点的左右指针是不会变的.
    }
    
    public void printTreeLineByLine(BinaryNode root){
        Queue<BinaryNode> queue = new LinkedList<MyBinarySearchTree.BinaryNode>();
        
        int current = 1;//当前层未打印的结点个数
        int next = 0;//下一层待打印的结点个数
        
        queue.offer(root);
        BinaryNode currentNode;
        while(!queue.isEmpty())
        {
            currentNode = queue.poll();
            current--;
            System.out.print(currentNode.ele + " ");//打印当前节点
            
            if(currentNode.left != null)
            {
                queue.offer(currentNode.left);
                next++;
            }
            if(currentNode.right != null)
            {
                queue.offer(currentNode.right);
                next++;
            }
            
            if(current == 0)//表示本行所有的结点已经打印完了
            {
                System.out.println();//打印下一行
                current = next;
                next = 0;
            }
        }
    }
    
    
    public void buildCompleteTree(int[] nodes){
        Queue<BinaryNode> queue = new LinkedList<BinaryNode>();
        root = new BinaryNode(nodes[0]);
        BinaryNode currentNode = null;
        
//        queue.offer(root);
        int next = 0;//标记当前结点的左右孩子是否已经构造完毕
        currentNode = root;//保存当前正在"构造"的结点
        int count = 1;//记录数组中的已经构造的元素
        while(count < nodes.length){
            if(next == 2)//某结点的左右孩子已经构造好了
            {
                currentNode = queue.poll();
                next = 0;
            }
            if(currentNode.left == null && count < nodes.length)
            {
                currentNode.left = new BinaryNode(nodes[count++]);
                queue.offer(currentNode.left);
                next++;
            }
            if(currentNode.right == null && count < nodes.length)
            {
                currentNode.right = new BinaryNode(nodes[count++]);
                queue.offer(currentNode.right);
                next++;
            }
        }    
    }
    
    
    //test
    public static void main(String[] args) {
        MyBinarySearchTree bst = new MyBinarySearchTree();
        int[] arr = {2,4,5,1,3};
//        bst.buildTree(arr);
//        bst.printTreeLineByLine(bst.root);
        
        System.out.println("----------------");
        
        bst.buildCompleteTree(arr);
        bst.printTreeLineByLine(bst.root);
    }
}
View Code

 

原文地址:博客园hapjin  http://www.cnblogs.com/hapjin/p/5738354.html

 

参考:构造二叉树,并求解树的高度


本文转自hapjin博客园博客,原文链接:http://www.cnblogs.com/hapjin/p/5738354.html,如需转载请自行联系原作者

相关文章
|
Ubuntu Linux 网络安全
Linux Debian11服务器安装SSH,创建新用户并允许远程SSH远程登录,并禁止root用户远程SSH登录
本文介绍了Linux Debian11服务器安装SSH,创建新用户并允许远程SSH远程登录,并禁止root用户远程SSH登录。
3575 1
Linux Debian11服务器安装SSH,创建新用户并允许远程SSH远程登录,并禁止root用户远程SSH登录
|
网络协议 前端开发 Java
SpringBoot+Netty开发IM即时通讯系列(一)
简单来讲,Netty是一个提供了易于使用的API的客户端/服务端框架。Netty并发非常高,一个非阻塞的IO,Netty传输速度也非常快,因为他是0拷贝,什么是零拷贝?NIO中的特性之一就是零拷贝,在Java中,内存分为堆和栈以及字符串常量值等等,如果有一些数据从IO中读取并且放到堆里面,中间会经过一些缓冲区。
1421 0
SpringBoot+Netty开发IM即时通讯系列(一)
|
搜索推荐 JavaScript Java
基于SpringBoot+Vue+uniapp的个性化新闻推荐系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的个性化新闻推荐系统的详细设计和实现(源码+lw+部署文档+讲解等)
210 1
|
网络协议 网络安全 Android开发
公网使用SSH远程连接安卓手机Termux - Android手机服务器
使用安卓机跑东西的时候,屏幕太小,有时候操作不习惯。不过我们可以开启ssh,使用电脑PC端SSH远程连接手机termux。 本次教程主要实现在安卓手机termux上安装SSH,在电脑上通过SSH远程连接Termux。同时在Termux上做内网穿透,用cpolar创建安全隧道映射22端口,实现在外也可以SSH远程连接Termux,无需公网IP,也不用设置路由器 ,这里使用国产内网穿透工具cpolar简单实现。
354 1
公网使用SSH远程连接安卓手机Termux - Android手机服务器
|
人工智能 前端开发 JavaScript
小说网站|基于Springboot+Vue实现在线小说阅读网站
本项目基于Springboot+Vue开发实现了一个在线小说阅读网站平台。系统设计用户主要有三类:读者、作者、管理员。用户注册时以读者身分进入平台,可以自己修改身分为作者。读者登录系统可以查看并在线阅读发布的小说章节内容,并在线评论、点赞和举报处理,同时可以查看平台发布的小说新闻和平台公告新闻。。作者登录平台除了可以查看小说外,还可以在线发布小说和内容,进行在线创作。所有的信息由平台管理员进行管理操作,包含人员管理、小说管理、章节管理、类型管理、举报管理、评论管理、新闻管理、系统管理(轮播图管理、超链接管理)等。
584 1
|
XML 前端开发 JavaScript
视频弹幕设计网站02-----数据库设计与后端配置
视频弹幕设计网站02-----数据库设计与后端配置
|
存储 Linux Python
Linux命令行上传文件到百度网盘
最近在学习 MySQL 的 bin-log 时候考虑到数据备份的问题,突然想到如果能将数据通过 Linux 命令行方式备份到百度网盘,那是一件多么牛逼的事情。百度网盘有免费的 2TB 存储空间,而且有百度做靠山,不怕数据丢失,安全可靠。
3529 0
|
JSON JavaScript Ubuntu
Ubuntu安装docker
Ubuntu安装docker
4913 0
|
Shell
Shell VSCode 基本开发插件(语法提示、错误检测、格式化、运行代码)
Shell VSCode 基本开发插件(语法提示、错误检测、格式化、运行代码)
2390 0
|
缓存 网络协议 程序员
解决GitHub下载速度太慢问题的方法汇总(持续更新,建议收藏)
解决GitHub下载速度太慢问题的方法汇总(持续更新,建议收藏)