利用队列构造链接式完全二叉树

  • 完全二叉树的定义

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

  • 数组式完全二叉树

将二叉树的节点按照层级顺序放入一个数组,就构建了一个数组式完全二叉树。根节点位于0,它的子节点位于1、2,子节点的子节点位于3、4、5、6,等等。这种构建方式非常简单,使用非常广泛,但是由于数组占用的是连续的内存,其大小不能灵活调整。

  • 链接式完全二叉树

一般的链接式二叉树可以将节点信息按照层次输入,再通过递归的方式构建。但是链接式完全二叉树的构建则完全不同,它需要满足定义中的特性:每层插入的节点总是连续的从左向右排列直到该层结点数达到最大个数。
由于先要从左向右插入本层节点,同时还要记录下一层的插入位置;当本层达到最大个数,则在下一层从左向右插入节点。这个过程符合队列的一系列入队和出队操作,故可以利用队列按层次顺序构建完全二叉树。

  • 完全二叉树构建的实现
public class CompleteBiTree<T> {
    private class Node {
        T item;
        Node lchild, rchild;
    }
    private Node root;// 二叉树的根节点
    private ListQueue<Node> queue = new ListQueue<>();// 层次信息的队列
    private int currentLength;

    public CompleteBiTree() {
        root = new Node();
        queue.enqueue(root);// 首先让根节点入队
        currentLength = 0;
    }

    public void insert(T v) {
        if (isEmpty()) {
            root.item = v;
            currentLength++;
            return;
        }
        Node newNode = new Node();// 新建节点
        newNode.item = v;
        while (!queue.isEmpty()) {
            Node t = queue.peek();// 取队头节点但不出队
            if (t.lchild == null) {
                t.lchild = newNode;
                currentLength++;
                return;// 仅有左孩子的节点并不出队,之后插入其右孩子
            }
            if (t.rchild == null) {
                t.rchild = newNode;
                queue.dequeue();// 插入右孩子后的节点处理完毕,让其出队
                queue.enqueue(t.lchild);// 将左右孩子入队,为下一层节点
                queue.enqueue(t.rchild);
                currentLength++;
                return;
            }
        }
    }

    public void show() {// 按照广度优先的顺序遍历
        ListQueue<Node> itQueue = new ListQueue<>();// 层次信息的队列
        itQueue.enqueue(root);
        while (!itQueue.isEmpty()) {
            Node t = itQueue.dequeue();// 根节点出队
            System.out.print(t.item + " ");
            // 分别将左右孩子入队,成为下一层节点
            if (t.lchild != null) {
                itQueue.enqueue(t.lchild);
            }
            if (t.rchild != null) {
                itQueue.enqueue(t.rchild);
            }
        }
    }

    public boolean isEmpty() {
        return currentLength == 0;
    }

    public int size() {
        return currentLength;
    }

    public static void main(String[] args) {
        CompleteBiTree<Integer> tree = new CompleteBiTree<>();
        for (int i = 0; i < 10; i++) {
            tree.insert(i);
        }
        tree.show();
    }
}

这就构造了链接式的完全二叉树,其中使用的简单链接式队列代码如下:

import java.util.Iterator;
// 链表队列
public class ListQueue<T> { 
    private class Node{
        T item;
        Node next;
    }
    private Node first;
    private Node last;
    private int currentLength;

    public void enqueue(T item) {
        Node newNode=new Node();
        newNode.item=item;
        if (isEmpty()) {
            last=newNode;
            first=last;
        }else{
            last.next=newNode;
            last=newNode;
        }
        ++currentLength;
    }

    public T dequeue() {
        T item=first.item;
        first=first.next;
        if (isEmpty()) {
            last=first;
        }
        --currentLength;
        return item;
    }

    public T peek() {
        Node f=first;
        return (f==null)?null:f.item;
    }

    public boolean isEmpty() {
        return first==null;
    }

    public int size() {
        return currentLength;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值