二叉树的构造

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

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

比如: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;//标记当前结点的左右孩子是否已经构造完毕
 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);
    }
}

时间: 2024-11-05 13:45:09

二叉树的构造的相关文章

数据结构例程——二叉树的构造

本文是数据结构基础系列(6):树和二叉树中第13课时二叉树的构造的例程. 1.由先序序列和中序序列构造二叉树 定理:任何n(n≥0)个不同节点的二叉树,都可由它的中序序列和先序序列唯一地确定. 证明(数学归纳法) 基础:当n=0时,二叉树为空,结论正确. 假设:设节点数小于n的任何二叉树,都可以由其先序序列和中序序列唯一地确定. 归纳:已知某棵二叉树具有n(n>0)个不同节点,其先序序列是a0a1-an?1:中序序列是b0b1-bk?1bkbk+1-bn?1. 先序遍历"根-左-右&quo

二叉树的构造和遍历——递归实现

一.二叉树的定义: 二叉树是每个结点最多有两个子树的有序树.二叉树常被用于实现二叉查找树.值得注意的是,二叉树不是树的特殊情形.在图论中,二叉树是一个连通的无环图,并且每一个顶点的度不大于2.有根二叉树还要满足根结点的度不大于2.有了根结点后,每个顶点定义了唯一的根结点,和最多2个子结点.然而,没有足够的信息来区分左结点和右结点. 二.二叉树与树的区别: 二叉树不是树的一种特殊情形,尽管其与树有许多相似之处,但树和二 叉树有两个主要差别: 1. 树中结点的最大度数没有限制,而二叉树结点的最大度数

二叉树的构造与遍历(前序、中序、后序)

注意: 构造二叉树的时候要用双重指针,用单重指针时,要有返回值. 代码如下: /* 此处输入空格代表空,默认按前序遍历完全二叉树的方式输入数据 形参是在执行函数时自动分配的,没有执行这个函数之前不占用存 储空间,当函数执行完毕后释放这个形参,所以我们要使用到双重指 针来构造树.这样,我们传进去的是树节点的指针的指针,这样函数 执行完成后即使这个“指针的指针“被释放掉了,我们通过*T保存的树 结点的数据还是可以通过树节点的指针T来调用.相反,如果我们传 进去如果是树结点的指针,当这个函数执行完毕后

数据结构之二叉树 (构造 拷贝构造 以及前序中序后续三种遍历方法)

首先二叉树的节点定义如下: struct BinaryNode {                  BinaryNode *_left;                  BinaryNode *_right;                  T _data;                 BinaryNode( T data ) :_data(data), _left( NULL), _right(NULL )                 {}; }; 二叉树的结构以及接口如下 te

二叉树的构造_遍历_求数高和求节点数

1 //手工构造一颗二叉树 ,并给出递归和非递归2类7种遍历方法,树高,节点数求法和逆时针90度显示二叉树 2 //注意本文中2个 typename的使用层次 3 //递归遍历容易溢栈 4 #include <cstdlib> 5 #include <iostream> 6 #include <queue> //用到队列时需要包含此文件 7 #include <stack> //用到栈时需要包含此文件 8 9 using namespace std; 10

算法题:二叉树的构造

#include <iostream> using namespace std; template<typename Type> struct Node { Node<Type> *right; Node<Type> *left; Type data; Node(Type d = Type()) :data(d), right(NULL), left(NULL){} }; template<typename Type> class MyTree

二叉树的构造与遍历

1 #include <iostream> 2 using namespace std; 3 4 typedef struct node 5 { 6 char data; 7 struct node *lchild; 8 struct node *rchild; 9 }BiTreeNode,*BiTree; 10 11 void createBiTree(BiTree &T) 12 { 13 char c; 14 cin>>c; 15 if(c=='#') T=NULL;

二叉树构造

同一棵二叉树(节点值均不相同)具有唯一的先序.中序.后序序列和层次序列,但不同的二叉树可能具有相同的先序.中序序列.后序序列和层次序列,二叉树的构造就是根据提供的某些遍历序列构造二叉树的结构. 由先序序列和中序序列构造二叉树:先序序列提供了二叉树的根节点的信息(任何一棵二叉树的先序序列的第一个节点为根节点),而中序序列提供了由根节点将整个序列分为左.右子树的信息. 确定树的根节点:先序遍历的第一个节点 求解树的子树:找出根节点在中序遍历中的位置,根左边的是左子树,右边的是右子树. 递归求解树:将

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

一,问题描述 在控制台上输入一组数据,请按照输入的数据的格式来构造一棵二叉树,并打印出二叉树的高度. 输入的数据格式如下: 第一行为一个整数N(其实是二叉树中边的数目),表示接下来一共有N行输入,每行输入有两个数,左边的数表示父结点,右边的数表示父结点的孩子结点.示例如下: 6 0 1 0 2 1 3 2 4 2 5 4 6 从上面的输入可以看出:①根结点0 的左孩子为1,右孩子为2 .②结点1 只有一个孩子,即左孩子3 二,问题分析 问题的关键是根据上面的输入数据 构造一棵二叉树. 首先用一个