堆排序
class Solution {
// 大根堆排序
public void heapSort(int[] arr){
if (arr == null || arr.length < 2) return;
// 将数组按大根堆排序,则 arr[0]是数组中最大的值
for (int i = 0; i < arr.length; i++) {
heapInsert(arr,i);
}
int size = arr.length;
// 把数组中最大的值放到末尾
swap(arr,0,--size);
// 将数组的末尾不断删除,再堆化
while (size > 0){
heapify(arr,0,size);
swap(arr,0,--size);
}
}
public void heapInsert(int[] arr,int index){
// 找到父节点的下标
int father = (index - 1) / 2;
// 只要子节点比父节点大就一直交换下去
while (arr[index] > arr[father]){
swap(arr,index,father);
index = father;
father = (index - 1) / 2;
}
}
public void heapify(int[] arr,int index,int size){
// 找到index的左右孩子下标left right
int left = 2 * index + 1;
while (left < size){
int right = left + 1;
// largest为index left right三者最大的下标
int largest = right < size && arr[right] > arr[left] ? right : left;
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index){
break;
}
swap(arr,largest,index);
index = largest;
left = 2 * index + 1;
}
}
public void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = new int[]{3,5,2,7,1,9,6};
solution.heapSort(nums);
System.out.println("1");
}
}
堆排序扩展题目
已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。
public class Code04_SortArrayDistanceLessK {
public void sortedArrDistanceLessK(int[] arr, int k) {
PriorityQueue<Integer> heap = new PriorityQueue<>();
int index = 0;
for (; index < Math.min(arr.length, k); index++) {
heap.add(arr[index]);
}
int i = 0;
for (; index < arr.length; i++, index++) {
heap.add(arr[index]);
arr[i] = heap.poll();
}
while (!heap.isEmpty()) {
arr[i++] = heap.poll();
}
}
}
桶排序(基数排序)
class Solution {
public void radixSort(int[] arr){
if (arr == null || arr.length < 2) return;
radixSort(arr,0,arr.length - 1,maxbits(arr));
}
// 算出数组中最大的位数 如[13,21,11,52,62,100] 最大位数为3
public int maxbits(int[] arr){
int max = Integer.MIN_VALUE;
for (int i : arr) {
max = Math.max(max,i);
}
int result = 0;
while (max > 0){
result++;
max /=10;
}
return result;
}
public void radixSort(int[] arr, int begin, int end, int digit){
final int radix = 10;
//桶的长度与arr数组相同
int[] bucket = new int[end - begin + 1];
// 最大位数是3的话,就需要进行三次进桶出桶
for (int d = 1; d <= digit; d++){
int[] count = new int[radix];
for (int i : arr) {
count[getDigit(i,d)]++;
}
for (int i = 1; i < count.length; i++) {
count[i] = count[i] + count[i - 1];
}
for (int j = end; j >= begin; j--){
bucket[count[getDigit(arr[j],d)] - 1] = arr[j];
count[getDigit(arr[j],d)]--;
}
for (int i = 0; i < bucket.length; i++) {
arr[i] = bucket[i];
}
}
}
// 取出d位上的数字 如 x=101,d=1是取出个位上的数字1,d=2是取出十位上的数字0
public int getDigit(int x, int d){
return (x / (int) Math.pow(10,d - 1)) % 10;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = new int[]{17,13,25,100,72};
solution.radixSort(nums);
System.out.println("1");
}
}