大根堆

  1. public class Heap {
  2. int[] nums = new int[10];
  3. int heapSize = 0;
  4. public static void main(String[] args) {
  5. Heap heap = new Heap();
  6. heap.add(4);
  7. heap.add(1);
  8. heap.add(3);
  9. heap.add(6);
  10. heap.add(2);
  11. heap.add(9);
  12. heap.add(4);
  13. // 9
  14. int remove1 = heap.remove();
  15. // 6
  16. int remove2 = heap.remove();
  17. // 4
  18. int remove3 = heap.remove();
  19. // 4
  20. int remove4 = heap.remove();
  21. // 3
  22. int remove5 = heap.remove();
  23. heap.add(10);
  24. // 10
  25. int remove6 = heap.remove();
  26. System.out.println();
  27. }
  28. private void add(int num){
  29. if (heapSize == nums.length){
  30. synchronized (nums){
  31. int[] numsNew = new int[nums.length + 10];
  32. System.arraycopy(nums,0,numsNew,0,nums.length);
  33. nums = numsNew;
  34. }
  35. }
  36. nums[heapSize] = num;
  37. up(heapSize);
  38. heapSize++;
  39. }
  40. private int remove(){
  41. int num = nums[0];
  42. nums[0] = nums[--heapSize];
  43. down(0);
  44. return num;
  45. }
  46. /**
  47. * index位置和父节点比较,大于父节点就交换
  48. */
  49. private void up(int index){
  50. int parentIndex = (index-1)/2;
  51. while (nums[index] > nums[parentIndex]){
  52. swap(nums,index,parentIndex);
  53. index = parentIndex;
  54. parentIndex = (index-1)/2;
  55. }
  56. }
  57. /**
  58. * index和子节点比较,子节点先选出最大的,然后和index比较,index小的话则交换
  59. */
  60. private void down(int index){
  61. int leftChildIndex = 2 * index + 1;
  62. while (leftChildIndex < heapSize){
  63. int maxChildIndex= leftChildIndex;
  64. if (leftChildIndex + 1 < heapSize && nums[leftChildIndex] < nums[leftChildIndex+1]){
  65. maxChildIndex++;
  66. }
  67. if (nums[index] >= nums[maxChildIndex]){
  68. return;
  69. }
  70. swap(nums,index,maxChildIndex);
  71. index = maxChildIndex;
  72. leftChildIndex = 2 * index + 1;
  73. }
  74. }
  75. private void swap(int[] nums, int i, int j){
  76. if (i == j) {
  77. return;
  78. }
  79. int temp = nums[i];
  80. nums[i] = nums[j];
  81. nums[j] = temp;
  82. }
  83. }

堆排序

从后往前做下调动作,这样能减少调整次数。调整完后变成一个大根堆
然后堆顶元素和最后元素做交换,堆空间减少1,然后让堆顶元素下沉调整。

  1. private void sort(int[] nums){
  2. this.nums = nums;
  3. heapSize = nums.length;
  4. //构建大根堆
  5. for (int i = nums.length-1; i >= 0; i--) {
  6. down(i);
  7. }
  8. //堆顶是最大值,直接放在最后,然后减少对size,在新size上对目前堆顶的元素进行调整
  9. while (heapSize > 0){
  10. swap(nums,0,--heapSize);
  11. down(0);
  12. }
  13. }