/// 堆積排序法。
fn heap_sort_inner(array: &mut [i32], shift_down: &dyn Fn(&mut [i32], usize, usize)) {
let length = array.len();
let length_dec = length - 1;
for start in (0..(length >> 1)).rev() {
shift_down(array, start, length_dec);
}
for i in (1..length).rev() {
array.swap(0, i);
shift_down(array, 0, i - 1);
}
}
#[inline]
fn heap_sort_shift_down(array: &mut [i32], mut start: usize, end: usize) {
loop {
let left = (start << 1) + 1;
if left > end {
break;
}
let right = left + 1;
let max_child = if right <= end && array[right] > array[left] {
right
} else {
left
};
if array[start] >= array[max_child] {
break;
}
array.swap(start, max_child);
start = max_child;
}
}
#[inline]
fn heap_sort_desc_shift_down(array: &mut [i32], mut start: usize, end: usize) {
loop {
let left = (start << 1) + 1;
if left > end {
break;
}
let right = left + 1;
let min_child = if right <= end && array[right] < array[left] {
right
} else {
left
};
if array[start] <= array[min_child] {
break;
}
array.swap(start, min_child);
start = min_child;
}
}
/// 堆積排序法(遞增)。
pub fn heap_sort(array: &mut [i32]) {
heap_sort_inner(array, &heap_sort_shift_down);
}
/// 堆積排序法(遞增)。
pub fn heap_sort_desc(array: &mut [i32]) {
heap_sort_inner(array, &heap_sort_desc_shift_down);
}
static abstract class ShiftDown {
abstract void shiftDown(final int[] array, int start, final int end);
}
static void heapSortInner(final int[] array, final ShiftDown shiftDown) {
final int length = array.length;
final int lengthDec = array.length;
for (int start = (length >> 1) - 1; start >= 0; --start) {
shiftDown.shiftDown(array, start, lengthDec);
}
for (int i = lengthDec; i >= 0; --i) {
final int temp = array[0];
array[0] = array[i];
array[i] = temp;
shiftDown.shiftDown(array, 0, i - 1);
}
}
static class AscShiftDown extends ShiftDown {
@Override
void shiftDown(final int[] array, int start, final int end) {
while (true) {
final int left = (start << 1) + 1;
if (left > end) {
break;
}
final int right = left + 1;
final int maxChild = (right <= end && array[right] > array[left]) ? right : left;
if (array[start] >= array[maxChild]) {
break;
}
final int temp = array[start];
array[start] = array[maxChild];
array[maxChild] = temp;
start = maxChild;
}
}
}
static class DescShiftDown extends ShiftDown {
@Override
void shiftDown(final int[] array, int start, final int end) {
while (true) {
final int left = (start << 1) + 1;
if (left > end) {
break;
}
final int right = left + 1;
final int minChild = (right <= end && array[right] < array[left]) ? right : left;
if (array[start] <= array[minChild]) {
break;
}
final int temp = array[start];
array[start] = array[minChild];
array[minChild] = temp;
start = minChild;
}
}
}
/**
* 堆積排序法(遞增)。
*/
public static void heapSort(final int[] array) {
heapSortInner(array, new AscShiftDown());
}
/**
* 堆積排序法(遞減)。
*/
public static void heapSortDesc(final int[] array) {
heapSortInner(array, new DescShiftDown());
}
/**
* 堆積排序法。
*/
function heapSortInner(array: number[], shiftDown: (array: number[], start: number, end: number) => void) {
const length = array.length;
const lengthDec = length - 1;
for (let start = (length >> 1) - 1;start >= 0;start--) {
shiftDown(array, start, lengthDec);
}
for (let i = lengthDec;i >= 1;i--) {
const temp = array[0];
array[0] = array[i];
array[i] = temp;
shiftDown(array, 0, i - 1);
}
}
function heapSortShiftDown(array: number[], start: number, end: number) {
for (; ;) {
const left = (start << 1) + 1;
if (left > end) {
break;
}
const right = left + 1;
const maxChild = right <= end && array[right] > array[left] ? right : left;
if (array[start] >= array[maxChild]) {
break;
}
const temp = array[start];
array[start] = array[maxChild];
array[maxChild] = temp;
start = maxChild;
}
}
function heapSortDescShiftDown(array: number[], start: number, end: number) {
for (; ;) {
const left = (start << 1) + 1;
if (left > end) {
break;
}
const right = left + 1;
const minChild = right <= end && array[right] < array[left] ? right : left;
if (array[start] <= array[minChild]) {
break;
}
const temp = array[start];
array[start] = array[minChild];
array[minChild] = temp;
start = minChild;
}
}
/**
* 堆積排序法(遞增)。
*/
function heapSort(array: number[]) {
heapSortInner(array, heapSortShiftDown);
}
/**
* 堆積排序法(遞減)。
*/
function heapSortDesc(array: number[]) {
heapSortInner(array, heapSortDescShiftDown);
}
// 堆積排序法。
func heapSortInner(array []int, shiftDown func([]int, int, int)) {
length := len(array)
lengthDec := length - 1
for start := (length >> 1) - 1; start >= 0; start -= 1 {
shiftDown(array, start, lengthDec)
}
for i := lengthDec; i >= 1; i -= 1 {
array[0], array[i] = array[i], array[0]
shiftDown(array, 0, i-1)
}
}
func heapSortShiftDown(array []int, start int, end int) {
for {
left := (start << 1) + 1
if left > end {
break
}
right := left + 1
var maxChild int
if right <= end && array[right] > array[left] {
maxChild = right
} else {
maxChild = left
}
if array[start] >= array[maxChild] {
break
}
array[start], array[maxChild] = array[maxChild], array[start]
start = maxChild
}
}
func heapSortDescShiftDown(array []int, start int, end int) {
for {
left := (start << 1) + 1
if left > end {
break
}
right := left + 1
var minChild int
if right <= end && array[right] < array[left] {
minChild = right
} else {
minChild = left
}
if array[start] <= array[minChild] {
break
}
array[start], array[minChild] = array[minChild], array[start]
start = minChild
}
}
// 堆積排序法(遞增)。
func HeapSort(array []int) {
heapSortInner(array, heapSortShiftDown)
}
// 堆積排序法(遞減)。
func HeapSortDesc(array []int) {
heapSortInner(array, heapSortDescShiftDown)
}