您的位置:首页 > 其它

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

2015-10-23 13:32 204 查看
完全二叉树的定义

若设二叉树的深度为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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: