论坛首页 Java企业应用论坛

Java最小堆实现

浏览 6600 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (18) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-05-31   最后修改:2010-05-31
1.堆结点
package boke.heap1;

/**
 * 堆结点
 * 
 * @since jdk1.5及其以上
 * @author 毛正吉
 * @version 1.0
 * @date 2010.05.24
 * 
 */
public class Node {
	private int iData; // 结点数据是整型

	public Node(int key) {
		iData = key;
	}

	/**
	 * setKey
	 * 
	 * @param id
	 */
	public void setKey(int id) {
		iData = id;
	}

	/**
	 * getKey
	 * 
	 * @return
	 */
	public int getKey() {
		return iData;
	}
}

2. 最小堆

package boke.heap1;

import boke.heap.Node;

/**
 * 最小堆
 * 
 * @since jdk1.5及其以上
 * @author 毛正吉
 * @version 1.0
 * @date 2010.05.24
 * 
 */
public class MinHeap {
	private Node[] heapArray; // 堆容器
	private int maxSize; // 堆得最大大小
	private int currentSize; // 堆大小

	public MinHeap(int _maxSize) {
		maxSize = _maxSize;
		heapArray = new Node[maxSize];
		currentSize = 0;
	}

	/**
	 * 自上而下调整
	 * 
	 * @param start
	 * @param endOfHeap
	 */
	public void filterDown(int start, int endOfHeap) {
		int i = start;
		int j = 2 * i + 1; // j是i的左子女位置
		Node temp = heapArray[i];

		while (j <= endOfHeap) { // 检查是否到最后位置
			if (j < endOfHeap // 让j指向两子女中的小者
					&& heapArray[j].getKey() > heapArray[j + 1].getKey()) {
				j++;
			}
			if (temp.getKey() <= heapArray[j].getKey()) { // 小则不做调整
				break;
			} else { // 否则小者上移,i,j下降
				heapArray[i] = heapArray[j];
				i = j;
				j = 2 * j + 1;
			}
		}
		heapArray[i] = temp;
	}

	/**
	 * 自下而上的调整:从结点start开始到0为止,自下向上比较,如果子女的值小于双亲结点的值则互相交换
	 * 
	 * @param start
	 */
	public void filterUp(int start) {
		int j = start;
		int i = (j - 1) / 2;
		Node temp = heapArray[j];

		while (j > 0) { // 沿双亲结点路径向上直达根节点
			if (heapArray[i].getKey() <= temp.getKey()) {// 双亲结点值小,不调整
				break;
			} else {// 双亲结点值大,调整
				heapArray[j] = heapArray[i];
				j = i;
				i = (i - 1) / 2;
			}
			heapArray[j] = temp; // 回送
		}
	}

	/**
	 * 堆中插入结点
	 * 
	 * @param key
	 * @return
	 * @throws MinHeapException
	 */
	public boolean insert(int key) throws MinHeapException {
		boolean bool = true;
		if (isFull()) {
			bool = false;
			throw new MinHeapException("MinHeap is full!");
		} else {
			Node newNode = new Node(key);
			heapArray[currentSize] = newNode;
			filterUp(currentSize);
			currentSize++;
		}
		return bool;
	}

	/**
	 * 删除堆中的最小值
	 * 
	 * @return
	 * @throws MinHeapException
	 */
	public Node removeMin() throws MinHeapException {
		if (isEmpty()) {
			throw new MinHeapException("MinHeap is empty!");
		}
		Node root = heapArray[0];
		heapArray[0] = heapArray[currentSize - 1];
		currentSize--;
		filterDown(0, currentSize - 1);
		return root;
	}

	/**
	 * 按某种格式输出堆
	 */
	public void displayHeap() {
		System.out.print("heapArray: ");
		for (int i = 0; i < currentSize; i++) {
			if (heapArray[i] != null) {
				System.out.print(heapArray[i].getKey() + " ");
			} else {
				System.out.print("-- ");
			}
		}
		System.out.println();

		int nBlanks = 32; // heap format
		int itemsPerRow = 1;
		int column = 0;
		int j = 0; // current item
		String dots = "...............................";
		System.out.println(dots + dots); // dotted top line

		while (currentSize > 0) { // for each heap item
			if (column == 0) { // first item in row
				for (int k = 0; k < nBlanks; k++) { // preceding blanks
					System.out.print(" ");
				}
			}
			System.out.print(heapArray[j].getKey()); // display item

			if (++j == currentSize) { // done?
				break;
			}

			if (++column == itemsPerRow) { // end of row?
				nBlanks /= 2; // half the blanks
				itemsPerRow *= 2; // twice the items
				column = 0; // start over on
				System.out.println(); // next row
			} else { // next item on row
				for (int k = 0; k < nBlanks * 2 - 2; k++) {
					System.out.print(' '); // interim blanks
				}
			}
		}
		System.out.println("\n" + dots + dots);
	}

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

	public boolean isFull() {
		return currentSize == maxSize;
	}

	public void makeEmpty() {
		currentSize = 0;
	}
}

3. 堆异常

package boke.heap1;

/**
 * 堆异常
 * 
 * @since jdk1.5及其以上
 * @author 毛正吉
 * @version 1.0
 * @date 2010.05.24
 * 
 */
public class MinHeapException extends Exception {
	public MinHeapException() {
		super("MinHeapException");
	}

	public MinHeapException(String exMsg) {
		super(exMsg);
	}
}

4.  最小堆应用测试

package boke.heap1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 最小堆应用测试
 * 
 * @since jdk1.5及其以上
 * @author 毛正吉
 * @version 1.0
 * @date 2010.05.24
 * 
 */
public class MinHeapApp {

	/**
	 * @param args
	 * @throws IOException
	 * @throws MinHeapException
	 */
	public static void main(String[] args) throws IOException, MinHeapException {
		int value, value2;
		MinHeap hp = new MinHeap(31);
		boolean success;

		hp.insert(53);
		hp.insert(17);
		hp.insert(78);
		hp.insert(9);
		hp.insert(45);
		hp.insert(65);
		hp.insert(87);
		hp.insert(23);

		while (true) {
			System.out.print("Enter first letter of ");
			System.out.print("show, insert, remove: ");
			int choice = getChar();

			switch (choice) {
			case 's':
				hp.displayHeap();
				break;
			case 'i':
				System.out.print("Enter value to insert: ");
				value = getInt();
				success = hp.insert(value);
				if (!success) {
					System.out.println("Can't insert; heap is full");
				}
				break;
			case 'r':
				if (!hp.isEmpty()) {
					hp.removeMin();
				} else {
					System.out.println("Can't remove; heap is empty");
				}
				break;
			default:
				System.out.println("Invalid entry\n");
			}
		}

	}

	/**
	 * 获得控制台输入流
	 * 
	 * @return
	 * @throws IOException
	 */
	public static String getString() throws IOException {
		return new BufferedReader(new InputStreamReader(System.in)).readLine();
	}

	/**
	 * 获得控制台输入字符
	 * 
	 * @return
	 * @throws IOException
	 */
	public static char getChar() throws IOException {
		return getString().charAt(0);
	}

	/**
	 * 获得控制台输入整型
	 * 
	 * @return
	 * @throws NumberFormatException
	 * @throws IOException
	 */
	public static int getInt() throws NumberFormatException, IOException {
		return Integer.parseInt(getString());
	}

}
   发表时间:2010-05-31  
看懂了,是数据结构
0 请登录后投票
   发表时间:2010-05-31  
路在转角处 写道
看懂了,是数据结构

呵呵 程序可以运行测试一下,那样更直观
0 请登录后投票
   发表时间:2010-05-31  
对 hashtable 做个封装不行吗?
0 请登录后投票
   发表时间:2010-06-01  
zwhc 写道
对 hashtable 做个封装不行吗?

呵呵 可试试
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics