数据结构:堆的java实现

最近写java程序的时候,经常用到堆这种数据结构,但是java本身的JDK本没有提供这种数据结构的实现。(栈,队列都有,为什么就不实现一个堆呢……图这种数据结构没有,我是可以理解的,但是堆为什么也没有呢?我就不理解了。有哪位大神知道原因的话,告诉我一下吧0.0)


由于上述原因,我就自己写了一个简单的堆实现。

实现的功能有:堆排序,创建大根堆,创建小根堆,增删改查等基本功能。底层运用的数据结构为:ArrayList。

为了比较方便,以及避免使用java自带的比较器(感觉返回值是一个int类型,1,0,-1什么的,感觉学习成本真高啊……分分钟忘记返回什么,才表示第一个比第二个对象,要“大”),所以自己就在heap类中,重新自己定义了一个简单的比较器接口,通过返回true或者false,告诉heap,是第一个对象“大”,还是第二个对象“大”。


注释的代码,就是一些测试代码,使用的时候,删掉即可。


废话少说,直接上代码:


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Heap<E> {

//	public static void main(String[] args) {
//		Heap<Integer> heap = new Heap<Integer>(new HeapComparator<Integer>() {
//
//			@Override
//			public boolean isFirstLargerThanSecond(Integer elem1, Integer elem2) {
//				return elem1 >= elem2 ? true : false;
//
//			}
//
//		}, 100);
//
//		heap.add(2, false);
//		heap.add(10, false);
//		heap.add(7, false);
//		heap.add(8, false);
//		heap.add(9, false);
//		heap.add(90, false);
//		heap.add(34, false);
//		heap.add(23, false);
//		heap.add(21, false);
//		heap.createMinHeap();
//		heap.printHeap();
//		heap.createMaxHeap();
//		heap.printHeap();
//		heap.remove(new Integer(23), true);
//		heap.printHeap();
//		heap.createMinHeap();
//		heap.printHeap();
//	}

	private List<E> list = null;
	private HeapComparator<E> comparator = null;
	// 表示当前大根堆还是小根堆。true表示为大根堆,false表示为小根堆
	private boolean isMaxHeap = false;

	public Heap() {
		list = new ArrayList<E>();
	}

	public Heap(HeapComparator<E> comparator) {
		list = new ArrayList<E>();
		this.comparator = comparator;
	}

	public Heap(HeapComparator<E> comparator, int size) {
		list = new ArrayList<E>(size);
		this.comparator = comparator;
	}

	/**
	 * @param e
	 * @param isMaintain
	 *            如果未false的话,表示仅仅是添加一个元素,并不会自动去维护堆的关系,所以,这个时候可能已经不再符合堆的结构约束了
	 *            如果未true的话,就会去维护堆的结构约束。
	 */
	public void add(E e, boolean isMaintain) {
		list.add(e);

		if (isMaintain) {
			int end = list.size() - 1;
			int begin = end / 2;

			while (true) {
				heapAdjust(begin, end);
				end = begin;
				if (end == 0) {
					break;
				}
				begin = (end - 1) / 2;
			}

		}
	}

	public void addAll(List<E> elems, boolean isMaintain) {
		list.addAll(elems);

		if (isMaintain) {
			heapSort();
		}
	}

	public void remove(E e, boolean isMaintain) {
		remove(list.indexOf(e), isMaintain);
	}

	public void remove(int index, boolean isMaintain) {
		if (isMaintain) {
			if (index >= list.size()) {
				throw new RuntimeException("超出长度了");
			}

			if (index == list.size() - 1) {
				list.remove(index);
				return;
			}
			// 用最后一个替代,然后再重新维护堆结构
			list.set(index, list.remove(list.size() - 1));
			heapAdjust(index, list.size() - 1);
		} else {
			list.remove(index);
		}
	}

	private void heapSort() {
		int begin = list.size() / 2 - 1;

		while (begin >= 0) {
			heapAdjust(begin, list.size() - 1);
			begin--;
		}
	}

	private void heapAdjust(int begin, int end) {
		if (comparator == null) {
			throw new RuntimeException("比较器不能为空");
		}

		boolean flag = true;
		if (isMaxHeap) {
			flag = true;
		} else {
			flag = false;
		}

		int child = begin * 2 + 1;
		E temp = null;
		int replaceIndex = 0;

		while (child <= end) {
			replaceIndex = child;

			if (child + 1 <= end) {
				if (isMaxHeap) {
					// 返回更大的对象
					flag = comparator.isFirstLargerThanSecond(
							list.get(child + 1), list.get(child));
					replaceIndex = flag == true ? child + 1 : child;
				} else {
					flag = comparator.isFirstLargerThanSecond(
							list.get(child + 1), list.get(child));
					replaceIndex = flag == true ? child : child + 1;
				}

			}

			temp = list.get(begin);
			if ((isMaxHeap && comparator.isFirstLargerThanSecond(
					list.get(replaceIndex), temp))
					|| (!isMaxHeap && !comparator.isFirstLargerThanSecond(
							list.get(replaceIndex), temp))) {
				list.set(begin, list.get(replaceIndex));
				list.set(replaceIndex, temp);
			}

			begin = replaceIndex;
			child = begin * 2 + 1;
		}
	}

	public void createMaxHeap() {
		isMaxHeap = true;
		heapSort();
	}

	public void createMinHeap() {
		isMaxHeap = false;
		heapSort();
	}

	public void printHeap() {
		System.out.println(list);
	}

	public Iterator<E> getIterator() {
		return list.iterator();
	}

	public E get(int index) {
		return list.get(index);
	}

	/**
	 * 返回底层的数据结构,方便直接使用原有List提供的功能
	 * 
	 * @return
	 */
	public List<E> getUnderlyingStructure() {
		return list;
	}

	public HeapComparator<E> getComparator() {
		return comparator;
	}

	public void setComparator(HeapComparator<E> comparator) {
		this.comparator = comparator;
	}

	interface HeapComparator<E> {
		/**
		 * 第一个元素比第二个大的话,返回true
		 * 
		 * @param elem1
		 * @param elem2
		 * @return
		 */
		boolean isFirstLargerThanSecond(E elem1, E elem2);
	}
}



谢谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值