package io.mycat.sqlengine.tmp; import io.mycat.server.packet.RowDataPacket; import java.util.ArrayList; import java.util.List; /** * 最大堆排序,适用于顺序排序 * * @author coderczp-2014-12-8 */ public class MaxHeap implements HeapItf { private RowDataCmp cmp; private List<RowDataPacket> data; public MaxHeap(RowDataCmp cmp, int size) { this.cmp = cmp; this.data = new ArrayList<>(); } @Override public void buildHeap() { int len = data.size(); for (int i = len / 2 - 1; i >= 0; i--) { heapifyRecursive(i, len); } } private void heapify(int i, int size) { int max = 0; int mid = size >> 1;// ==size/2 while (i <= mid) { max = i; int left = i << 1; int right = left + 1; if (left < size && cmp.compare(data.get(left), data.get(i)) > 0) { max = left; } if (right < size && cmp.compare(data.get(right), data.get(max)) > 0) { max = right; } if (i == max) break; if (i != max) { RowDataPacket tmp = data.get(i); data.set(i, data.get(max)); data.set(max, tmp); i = max; } } } // 递归版本 protected void heapifyRecursive(int i, int size) { int l = left(i); int r = right(i); int max = i; if (l < size && cmp.compare(data.get(l), data.get(i)) > 0) max = l; if (r < size && cmp.compare(data.get(r), data.get(max)) > 0) max = r; if (i == max) return; swap(i, max); heapifyRecursive(max, size); } private int right(int i) { return (i + 1) << 1; } private int left(int i) { return ((i + 1) << 1) - 1; } private void swap(int i, int j) { RowDataPacket tmp = data.get(i); RowDataPacket elementAt = data.get(j); data.set(i, elementAt); data.set(j, tmp); } @Override public RowDataPacket getRoot() { return data.get(0); } @Override public void setRoot(RowDataPacket root) { data.set(0, root); heapifyRecursive(0, data.size()); } @Override public List<RowDataPacket> getData() { return data; } @Override public void add(RowDataPacket row) { data.add(row); } @Override public boolean addIfRequired(RowDataPacket row) { // 淘汰堆里最小的数据 RowDataPacket root = getRoot(); if (cmp.compare(row, root) < 0) { setRoot(row); return true; } return false; } @Override public void heapSort(int size) { final int total = data.size(); // 容错处理 if (size <= 0 || size > total) { size = total; } final int min = size == total ? 0 : (total - size - 1); // 末尾与头交换,交换后调整最大堆 for (int i = total - 1; i > min; i--) { swap(0, i); heapifyRecursive(0, i); } } }