用java实现二叉查找树、堆和优先队列

   二叉查找树是以一种特殊的二叉树。它的特征是,没一个节点左子树中结点的值都小于该结点的值,右子树中

结点的值都大于该结点的值。

    二叉查找树的主要操作就是插入元素、删除元素、遍历元素。

    插入元素:如果二叉树是空的,使用新元素创建一个根节点;否则,为新元素寻找父节点。如果新元素的值小于父

节点的值,则将新元素的结点设置为父节点的左孩子;否则,将其设为右孩子。

    遍历元素:遍历主要有中序、前序、后序、深度优先、广度优先等。


下面这个类包括了结点的定义还有二叉树的定义。

package binaryTree;

public class BinaryTree {

	// 节点的定义
	private static class TreeNode {
		Object element;
		TreeNode left;
		TreeNode right;

		public TreeNode(Object o) {
			element = o;
		}
	}

	private TreeNode root;
	private int size = 0;

	public BinaryTree() {

	}

	public BinaryTree(Object[] objects) {
		for (int i = 0; i < objects.length; i++) {
			insert(objects[i]);
		}
	}

	public boolean insert(Object o) {
		if (root == null) {
			root = new TreeNode(o);
		} else {
			TreeNode parent = null;
			TreeNode current = root;
			while (current != null) {
				if (((Comparable) o).compareTo(current.element) < 0) {
					parent = current;
					current = current.left;
				} else if (((Comparable) o).compareTo(current.element) > 0) {
					parent = current;
					current = current.right;
				} else {
					return false;
				}
			}
			if (((Comparable) o).compareTo(parent.element) < 0) {
				parent.left = new TreeNode(o);
			} else {
				parent.right = new TreeNode(o);
			}
		}
		size++;
		return true;
	}

	//中序遍历
	public void inorder(){
		inorder(root);
	}
	public void inorder(TreeNode root){
		if (root == null) {
			return;
		}
		inorder(root.left);
		System.out.println(root.element + " ");
		inorder(root.right);
	}
	
	//后序遍历
	public void postorder(){
		postorder(root);
	}
	
	public void postorder(TreeNode root){
		if (root == null) {
			return;
		}
		postorder(root.left);
		postorder(root.right);
		System.out.println(root.element +" ");
	}
	
	//前序遍历
	public void preorder(){
		preorder(root);
	}
	
	public void preorder(TreeNode root){
		if (root == null) {
			return;
		}
		System.out.println(root.element + " ");
		preorder(root.left);
		preorder(root.right);
	}
	
	public int getSize(){
		return size;
	}
	
	
}

测试类:

package binaryTree;

public class TestBinaryTree {
	public static void main(String[] args) {
		BinaryTree tree = new BinaryTree();
		tree.insert("a");
		tree.insert("b");
		tree.insert("c");
		tree.insert("d");
		tree.insert("e");
		tree.insert("f");
		tree.insert("g");
		System.out.println("Inorder (sorted): ");
		tree.inorder();
		System.out.println("postorder: ");
		tree.postorder();
		System.out.println("preorder: ");
		tree.preorder();
		System.out.println("the number of nodes is " + tree.getSize());
	}

}

    是一种在设计有效的排序算法和优先队列时有用的数据结构。堆是一个完全二叉树,并且它的每个结点都大于

等于它的任何孩子结点。由于堆是二叉树,因此可以用二叉树数据结构来表示堆。然而,如果预先不知道堆的大小,一个更有效的表示是用数组或数组线性表。

    对于位置i处的结点,它的左孩子位于2i+1处,右孩子位于2i+2处,它的父亲结点位于(i-1)/2处。

    删除根结点。删除根节点之后要保持堆的特性,就需要一个算法了。

    Move the last node to replace the root;
    Let the root be the current node;
    while(the current node has children and the current node is smaller than one of its children){
        Swap the current node with the larger of its children;
        Now the current node is one level down;
    }

    添加一个新结点的算法是

 Let the last node be the current node;
    while(the current node is greater than its parent){
        Swap the current node with its parent;
        Now the current node is one level up;
    }

下面设计和实现Heap类。

package heap;

import java.util.ArrayList;

public class Heap {
	private ArrayList list = new ArrayList();

	public Heap() {

	}

	public Heap(Object[] objects) {
		for (int i = 0; i < objects.length; i++) {
			add(objects[i]);
		}
	}

	public void add(Object newObject) {
		list.add(newObject);
		//the index of the last node
		int currentIndex = list.size() - 1;

		while (currentIndex > 0) {
			//计算父节点的index
			int parentIndex = (currentIndex - 1) / 2;
			//如果当前节点大于他的父节点就交换
			if (((Comparable) (list.get(currentIndex))).compareTo(list
					.get(parentIndex)) > 0) {
				Object temp = list.get(currentIndex);
				list.set(currentIndex, list.get(parentIndex));
				list.set(parentIndex, temp);
			} else {
				break;
			}
			currentIndex = parentIndex;
		}
	}

	/**
	 * remove the root from the heap
	 * 
	 * @return
	 */
	public Object remove() {
		if (list.size() == 0) {
			return null;
		}
		//被删除的节点---根节点
		Object removedObject = list.get(0);
		
		//将最后一个移动到根节点
		list.set(0,  list.get(list.size() - 1));
		list.remove(list.size() - 1);
		
		int currentIndex = 0;
		while (currentIndex < list.size()) {
			//计算当前节点的左节点和右节点
			int leftChildIndex = 2 * currentIndex + 1;
			int rightChileIndex = 2 * currentIndex + 2;
			
			//找到两个子节点中最大的节点
			if (leftChildIndex >= list.size()) {
				break;
			}
			int maxIndex = leftChildIndex;
			if (rightChileIndex < list.size()) {
				if (((Comparable) (list.get(maxIndex))).compareTo(list
						.get(rightChileIndex)) < 0) {
					maxIndex = rightChileIndex;
				}
			}

			//如果当前节点小于子节点的最大值就交换
			if (((Comparable) (list.get(currentIndex))).compareTo(list
					.get(maxIndex)) < 0) {
				Object temp = list.get(maxIndex);
				list.set(maxIndex, list.get(currentIndex));
				list.set(currentIndex, temp);
				currentIndex = maxIndex;
			} else {
				break;
			}
		}
		return removedObject;
	}

	public int getSize() {
		return list.size();
	}

}

测试类:

package heap;

public class TestHeap {
	public static void main(String[] args) {
		Heap heap = new Heap(new Integer[] { 8, 9, 2, 4, 5, 6, 7, 5, 3, 0 });
		while (heap.getSize() > 0) {
			System.out.println(heap.remove() + " ");
		}
	}
}

    优先队列中,元素都赋予了优先级。当访问元素的时候,具有最高优先级的元素最先移除。优先队列具有最

高进先出的特性。可以使用堆来实现队列优先。

package priorityQueue;

import heap.Heap;

public class MyPriorityQueue {
	private Heap heap = new Heap();

	public void enqueue(Object newObject) {
		heap.add(newObject);
	}

	public Object dequeue() {
		return heap.remove();
	}

	public int getSize() {
		return heap.getSize();
	}

}

测试类:

package priorityQueue;

public class TestPriorityQueue {
	public static void main(String[] args) {
		Patient patient1 = new Patient("john", 2);
		Patient patient2 = new Patient("slmile", 0);
		Patient patient3 = new Patient("dohn", 5);
		Patient patient4 = new Patient("jack", 3);
		Patient patient5 = new Patient("sen", 7);

		MyPriorityQueue priorityQueue = new MyPriorityQueue();
		priorityQueue.enqueue(patient1);
		priorityQueue.enqueue(patient2);
		priorityQueue.enqueue(patient3);
		priorityQueue.enqueue(patient4);
		priorityQueue.enqueue(patient5);

		while (priorityQueue.getSize() > 0) {
			System.out.println(priorityQueue.dequeue() + " ");
		}
	}

}

class Patient implements Comparable {
	private String name;
	private int priority;

	public Patient(String name, int priority) {
		this.name = name;
		this.priority = priority;
	}

	public String toString() {
		return name + "(priority: " + priority + ")";
	}

	public int compareTo(Object o) {
		return this.priority - ((Patient) o).priority;
	}
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/crazy1235/article/details/8569830
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞