parent
7262612f63
commit
503cc2b69f
@ -0,0 +1,36 @@
|
|||||||
|
package leo.class03;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName Comparator
|
||||||
|
* @DATE 2020/11/27 10:22 上午
|
||||||
|
* @Description 比较器
|
||||||
|
* 实现comparator中的compare方法
|
||||||
|
* 两个参数
|
||||||
|
* 返回负数 第一个参数排在前面
|
||||||
|
* 返回0,谁都可以,
|
||||||
|
* 返回正数,第二个参数排在前面.
|
||||||
|
* arrays[数组] TreeSet,TreeMap[有序表]
|
||||||
|
* TreeMap 如果k两个对象一样,无法加入,不覆盖,[不加重复的K的]
|
||||||
|
* 如果想都留着,用hashCode()
|
||||||
|
* 优先级队列可以添加重复的K
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Comparator {
|
||||||
|
|
||||||
|
public static class Student{
|
||||||
|
String name;
|
||||||
|
Integer age;
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class MyComparator implements java.util.Comparator<Student>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Student o1, Student o2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
package leo.class03;
|
||||||
|
|
||||||
|
import leo.util.ArrayUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName HeapSort
|
||||||
|
* @DATE 2020/11/27 4:20 下午
|
||||||
|
* @Description 堆排序
|
||||||
|
* 最差时间复杂度为O(N*logN)
|
||||||
|
* 数据量扩倍法推算 堆排序的时间复杂度下限是O(N*logN)
|
||||||
|
* 上限和下限一样 所以时间复杂度为O(N*logN)
|
||||||
|
* 建堆的时间复杂度是O(N*logN)
|
||||||
|
* 每个数据插入的时间复杂度是O(logN)
|
||||||
|
*
|
||||||
|
* 从上往下建堆:O(N*logN) 一个一个数据插入只能从上往下建堆
|
||||||
|
* 从下往上建堆:O(N) [错位相减]所有的数据都有,可以从下往上建堆
|
||||||
|
* 堆结构要从上往下建堆
|
||||||
|
* 堆排序要从下往上建堆
|
||||||
|
* 堆排序额外空间复杂度O(1)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HeapSort {
|
||||||
|
|
||||||
|
|
||||||
|
public static void heapSort(int[] arr) {
|
||||||
|
if (arr.length < 2 || arr == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = arr.length - 1; i >= 0; i--) {
|
||||||
|
heapify(arr, i, arr.length);
|
||||||
|
}
|
||||||
|
int heapSize = arr.length;
|
||||||
|
|
||||||
|
while (heapSize > 0) {
|
||||||
|
swap(arr, 0, --heapSize);
|
||||||
|
heapify(arr, 0, heapSize);
|
||||||
|
}
|
||||||
|
swap(arr, 0, heapSize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void heapify(int[] arr, int i, int heapSize) {
|
||||||
|
int left = i << 1 | 1;
|
||||||
|
while (left < heapSize) {
|
||||||
|
int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
|
||||||
|
largest = arr[largest] > arr[i] ? largest : i;
|
||||||
|
if (largest == i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
swap(arr, i, largest);
|
||||||
|
i = largest;
|
||||||
|
left = i << 1 | 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void swap(int[] arr, int i, int j) {
|
||||||
|
if (i == j || arr[i] == arr[j]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
arr[j] = arr[i] ^ arr[j];
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MainHeapSort {
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
int testTime = 10000;
|
||||||
|
int sizeMax = 70;
|
||||||
|
int range = 50;
|
||||||
|
System.out.println("start");
|
||||||
|
|
||||||
|
for (int i = 0; i < testTime; i++) {
|
||||||
|
int[] arr = ArrayUtil.randomArray(sizeMax, range);
|
||||||
|
int[] copyArray = ArrayUtil.copyArray(arr);
|
||||||
|
Arrays.sort(copyArray);
|
||||||
|
HeapSort.heapSort(arr);
|
||||||
|
if (!ArrayUtil.isEqual(arr, copyArray)) {
|
||||||
|
ArrayUtil.printArr(arr);
|
||||||
|
ArrayUtil.printArr(copyArray);
|
||||||
|
|
||||||
|
System.out.println("fuck!");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("end");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,272 @@
|
|||||||
|
package leo.class03;
|
||||||
|
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName MyMaxHeap
|
||||||
|
* @DATE 2020/11/27 11:01 上午
|
||||||
|
* @Description 堆结构
|
||||||
|
* 堆结构比堆排序重要
|
||||||
|
* 优先级队列[PriorityQueue,默认是小根堆]结构就是堆结构.
|
||||||
|
* 完全二叉树:如果一个树是满的就是完全二叉树,如果一棵树不满,也是最后一层,也在变满的路上,如果一个树是从左到右变满的就是完全二叉树.
|
||||||
|
* 堆结构:用数组实现的完全二叉树结构,
|
||||||
|
* 大根堆:在完全二叉树中,每棵子树的最大值都在顶部
|
||||||
|
* 小根堆:在完全二叉树中,每棵子树的最小值都在顶部
|
||||||
|
* 堆结构操作:
|
||||||
|
* heapInsert 向上调整
|
||||||
|
* heapify 向下调整
|
||||||
|
* i 左子节点的位置:2*i+1
|
||||||
|
* i 右子节点的位置:2*i+2
|
||||||
|
* i 父节点的位置:(i-1)/2
|
||||||
|
*
|
||||||
|
*
|
||||||
|
|
||||||
|
*/
|
||||||
|
public class MyMaxHeap {
|
||||||
|
private final int limit;
|
||||||
|
private int heapSize;
|
||||||
|
private int[] arr;
|
||||||
|
|
||||||
|
public MyMaxHeap(int limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
this.heapSize = 0;
|
||||||
|
this.arr = new int[limit];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(int value) {
|
||||||
|
if (this.heapSize >= this.limit) {
|
||||||
|
throw new RuntimeException("heap is full");
|
||||||
|
}
|
||||||
|
this.arr[this.heapSize] = value;
|
||||||
|
heapInsert(arr, this.heapSize++);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int pop() {
|
||||||
|
if (heapSize == 0) {
|
||||||
|
throw new RuntimeException("heap is empty");
|
||||||
|
}
|
||||||
|
int value = this.arr[0];
|
||||||
|
this.swap(arr, 0, --heapSize);
|
||||||
|
heapify(arr, 0, heapSize);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return heapSize == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将index向上调整
|
||||||
|
*/
|
||||||
|
private void heapInsert(int[] arr, int index) {
|
||||||
|
|
||||||
|
while (arr[index] > arr[(index - 1) / 2]) {
|
||||||
|
this.swap(arr, index, (index - 1) / 2);
|
||||||
|
index = (index - 1) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void heapify(int[] arr, int index, int heapSize) {
|
||||||
|
int left = index << 1 | 1;
|
||||||
|
while (left < heapSize) {
|
||||||
|
//选择左右哪个子节点,哪个大选择那个
|
||||||
|
int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
|
||||||
|
largest = arr[largest] > arr[index] ? largest : index;
|
||||||
|
if (largest == index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
swap(arr, index, largest);
|
||||||
|
index = largest;
|
||||||
|
left = index << 1 | 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void swap(int[] arr, int i, int j) {
|
||||||
|
if (i == j || arr[i] == arr[j]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
arr[j] = arr[i] ^ arr[j];
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyMaxHeap1 {
|
||||||
|
|
||||||
|
private int size;
|
||||||
|
private final int limit;
|
||||||
|
private int[] arr;
|
||||||
|
|
||||||
|
|
||||||
|
MyMaxHeap1(int limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
this.arr = new int[limit];
|
||||||
|
this.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(int value) {
|
||||||
|
if (size == limit) {
|
||||||
|
throw new RuntimeException("heap is full");
|
||||||
|
}
|
||||||
|
arr[size] = value;
|
||||||
|
heapInsert(arr, size++);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int pop() {
|
||||||
|
if (size == 0) {
|
||||||
|
throw new RuntimeException("heap is empty!");
|
||||||
|
}
|
||||||
|
int value = this.arr[0];
|
||||||
|
this.swap(arr, 0, --size);
|
||||||
|
heapify(arr, 0, size);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void heapify(int[] arr, int i, int size) {
|
||||||
|
int left = i << 1 | 1;
|
||||||
|
while (left < size) {
|
||||||
|
int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
|
||||||
|
largest = arr[i] >= arr[largest] ? i : largest;
|
||||||
|
if (largest == i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
swap(arr, largest, i);
|
||||||
|
i = largest;
|
||||||
|
left = i << 1 | 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void heapInsert(int[] arr, int i) {
|
||||||
|
while (arr[i] > arr[(i - 1) / 2]) {
|
||||||
|
swap(arr, i, (i - 1) / 2);
|
||||||
|
i = (i - 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void swap(int[] arr, int i, int j) {
|
||||||
|
if (i == j || arr[i] == arr[j]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
arr[j] = arr[i] ^ arr[j];
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyMaxHeap2{
|
||||||
|
|
||||||
|
private int size;
|
||||||
|
private int[] arr;
|
||||||
|
private final int limit;
|
||||||
|
|
||||||
|
MyMaxHeap2(int limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
this.size = 0;
|
||||||
|
this.arr = new int[limit];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void push(int value) {
|
||||||
|
if (size == limit) {
|
||||||
|
throw new RuntimeException("heap is full");
|
||||||
|
}
|
||||||
|
this.arr[size] = value;
|
||||||
|
this.heapInsert(arr, size++);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int pop() {
|
||||||
|
int value = this.arr[0];
|
||||||
|
swap(this.arr, 0, --this.size);
|
||||||
|
heapify(arr, 0, this.size);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void heapify(int[] arr, int i, int size) {
|
||||||
|
int left = i << 1 | 1;
|
||||||
|
while (left < size) {
|
||||||
|
int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
|
||||||
|
largest = arr[largest] > arr[i] ? largest : i;
|
||||||
|
if (largest == i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
swap(arr, largest, i);
|
||||||
|
i = largest;
|
||||||
|
left = i << 1 | 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void heapInsert(int[] arr, int i) {
|
||||||
|
while (arr[i] > arr[(i - 1) / 2]) {
|
||||||
|
swap(arr, i, (i - 1) / 2);
|
||||||
|
i = (i - 1) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void swap(int[] arr, int i, int j) {
|
||||||
|
if (i == j || arr[i] == arr[j]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
arr[j] = arr[i] ^ arr[j];
|
||||||
|
arr[i] = arr[i] ^ arr[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Main{
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
|
||||||
|
int testTimes = 1000;
|
||||||
|
int range = 50;
|
||||||
|
System.out.println("start!");
|
||||||
|
PriorityQueue<Integer> queue = new PriorityQueue<>((a,b)-> {return b-a;});
|
||||||
|
MyMaxHeap2 heap = new MyMaxHeap2(testTimes);
|
||||||
|
for (int i = 0; i < testTimes; i++) {
|
||||||
|
if (heap.isEmpty()) {
|
||||||
|
int num = (int) ((range * Math.random() + 1) - (range * Math.random() + 1));
|
||||||
|
queue.add(num);
|
||||||
|
heap.push(num);
|
||||||
|
}else {
|
||||||
|
if (Math.random() < 0.5) {
|
||||||
|
int num = (int) ((range * Math.random() + 1) - (range * Math.random() + 1));
|
||||||
|
queue.add(num);
|
||||||
|
heap.push(num);
|
||||||
|
}else{
|
||||||
|
Integer poll = queue.poll();
|
||||||
|
int pop = heap.pop();
|
||||||
|
if (poll != pop) {
|
||||||
|
System.out.println(poll);
|
||||||
|
System.out.println(pop);
|
||||||
|
System.out.println("fuck!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("end!");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in new issue