219 阅读3分钟

堆的实现

`package mergeSort;

import java.util.Comparator; import java.util.PriorityQueue; public class Heap {

public static class MyMaxHeap{
	private int[] heap;
	private final int limit;
	private int heapSize;
	
	public MyMaxHeap(int limit) {
		heap= new int[limit];
		this.limit=limit;
		heapSize=0;
	}
	
	public boolean isEmpty() {
		return heapSize==0;
	}
	
	public boolean isFull() {
		return heapSize==limit;
	}
	
	public void push(int value) {
		if(heapSize==limit) {
			throw new RuntimeException("heap is full");
		}
		
		heap[heapSize]=value;
		
		heapInsert(heap, heapSize++);
	}
	
	public int pop() {
		int ans=heap[0];
		swap(heap,0,--heapSize);
		heapify(heap,0,heapSize);
		return ans;
	}
	
	private void heapInsert(int[] arr,int index) {
		while(index>(index-1)/2) {
			swap(heap,index,(index-1)/2);
			index=(index-1)/2;
		}
	}
	
	private void heapify(int[] arr,int index,int heapSize) {
		int left=index*2+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,largest,index);
			index=largest;
			left=index*2+1;
		}
	}
	
	private void swap(int[] arr,int i,int j) {
		int tmp=arr[i];
		arr[i]=arr[j];
		arr[j]=tmp;
	}
}



public static class RightMaxHeap {
	private int[] arr;
	private final int limit;
	private int size;

	public RightMaxHeap(int limit) {
		arr = new int[limit];
		this.limit = limit;
		size = 0;
	}

	public boolean isEmpty() {
		return size == 0;
	}

	public boolean isFull() {
		return size == limit;
	}

	public void push(int value) {
		if (size == limit) {
			throw new RuntimeException("heap is full");
		}
		arr[size++] = value;
	}

	public int pop() {
		int maxIndex = 0;
		for (int i = 1; i < size; i++) {
			if (arr[i] > arr[maxIndex]) {
				maxIndex = i;
			}
		}
		int ans = arr[maxIndex];
		arr[maxIndex] = arr[--size];
		return ans;
	}

}


public static class MyComparator implements Comparator<Integer>{

	@Override
	public int compare(Integer o1, Integer o2) {
		return o2 - o1;
	}
	
}

public static void main(String[] args) {
	// 小根堆

// PriorityQueue heap = new PriorityQueue<>(new MyComparator()); // heap.add(5); // heap.add(5); // heap.add(5); // heap.add(3); // // 5 , 3 // System.out.println(heap.peek()); // heap.add(7); // heap.add(0); // heap.add(7); // heap.add(0); // heap.add(7); // heap.add(0); // System.out.println(heap.peek()); // while(!heap.isEmpty()) { // System.out.println(heap.poll()); // }

	int value = 1000;
	int limit = 100;
	int testTimes = 1000000;
	for (int i = 0; i < testTimes; i++) {
		int curLimit = (int) (Math.random() * limit) + 1;
		MyMaxHeap my = new MyMaxHeap(curLimit);
		RightMaxHeap test = new RightMaxHeap(curLimit);
		int curOpTimes = (int) (Math.random() * limit);
		for (int j = 0; j < curOpTimes; j++) {
			if (my.isEmpty() != test.isEmpty()) {
				System.out.println("Oops!");
			}
			if (my.isFull() != test.isFull()) {
				System.out.println("Oops!");
			}
			if (my.isEmpty()) {
				int curValue = (int) (Math.random() * value);
				my.push(curValue);
				test.push(curValue);
			} else if (my.isFull()) {
				if (my.pop() != test.pop()) {
					System.out.println("Oops!");
				}
			} else {
				if (Math.random() < 0.5) {
					int curValue = (int) (Math.random() * value);
					my.push(curValue);
					test.push(curValue);
				} else {
					if (my.pop() != test.pop()) {
						System.out.println("Oops!");
					}
				}
			}
		}
	}
	System.out.println("finish!");

}

} `

堆排序

`package mergeSort;

import java.util.Arrays; import java.util.PriorityQueue;

public class c1_HeapSort {

public static void heapSort(int[] arr) {
	if(arr==null || arr.length<2) {
		return;
	}
	for(int i=arr.length-1;i>=0;i--) {
		heapify(arr,i,arr.length);
	}
	int heapSize=arr.length;
	swap(arr,0,--heapSize);
	while(heapSize>0) {
		heapify(arr,0,heapSize);
		swap(arr,0,--heapSize);
	}
}

public static void heapInsert(int[] arr,int index) {
	while(arr[index]>arr[(index-1)/2]) {
		swap(arr,index,(index-1)/2);
		index=(index-1)/2;
	}
}

public static void heapify(int[] arr,int index,int heapSize) {
	int left=index*2+1;
	while(left<heapSize) {
		int largest=left+1<heapSize && arr[left+1]>arr[left]?left+1:left;
		largest=arr[index]>arr[largest]?index:largest;
		if(largest==index) {
			break;
		}
		swap(arr,largest,index);
		index=largest;
		left=index*2+1;
	}
}



public static void swap(int[] arr, int i, int j) {
	int tmp = arr[i];
	arr[i] = arr[j];
	arr[j] = tmp;
}

// for test
public static void comparator(int[] arr) {
	Arrays.sort(arr);
}

// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
	int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
	for (int i = 0; i < arr.length; i++) {
		arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
	}
	return arr;
}

// for test
public static int[] copyArray(int[] arr) {
	if (arr == null) {
		return null;
	}
	int[] res = new int[arr.length];
	for (int i = 0; i < arr.length; i++) {
		res[i] = arr[i];
	}
	return res;
}

// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
	if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
		return false;
	}
	if (arr1 == null && arr2 == null) {
		return true;
	}
	if (arr1.length != arr2.length) {
		return false;
	}
	for (int i = 0; i < arr1.length; i++) {
		if (arr1[i] != arr2[i]) {
			return false;
		}
	}
	return true;
}

// for test
public static void printArray(int[] arr) {
	if (arr == null) {
		return;
	}
	for (int i = 0; i < arr.length; i++) {
		System.out.print(arr[i] + " ");
	}
	System.out.println();
}

// for test
public static void main(String[] args) {

	// 默认小根堆
	PriorityQueue<Integer> heap = new PriorityQueue<>();
	heap.add(6);
	heap.add(8);
	heap.add(0);
	heap.add(2);
	heap.add(9);
	heap.add(1);

	while (!heap.isEmpty()) {
		System.out.println(heap.poll());
	}

	int testTime = 500000;
	int maxSize = 100;
	int maxValue = 100;
	boolean succeed = true;
	for (int i = 0; i < testTime; i++) {
		int[] arr1 = generateRandomArray(maxSize, maxValue);
		int[] arr2 = copyArray(arr1);
		heapSort(arr1);
		comparator(arr2);
		if (!isEqual(arr1, arr2)) {
			succeed = false;
			break;
		}
	}
	System.out.println(succeed ? "Nice!" : "Fucking fucked!");

	int[] arr = generateRandomArray(maxSize, maxValue);
	int[] array = copyArray(arr);
	printArray(arr);
	heapSort(arr);
	comparator(array);
	printArray(arr);
	printArray(array);
}

}`

排序(位置变动不会超过k个)

`package mergeSort;

import java.util.Arrays; import java.util.PriorityQueue;

public class SortArrayDistanceLessK {

public static void sortedArrDistanceLessK(int[] arr, int k) {
	if(k==0) {
		return;
	}
	PriorityQueue<Integer> heap=new PriorityQueue<>();
	int index=0;
	for(;index<=Math.min(arr.length-1, k-1);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();
	}
}

// for test
public static void comparator(int[] arr, int k) {
	Arrays.sort(arr);
}

// for test
public static int[] randomArrayNoMoveMoreK(int maxSize, int maxValue, int K) {
	int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
	for (int i = 0; i < arr.length; i++) {
		arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
	}
	// 先排个序
	Arrays.sort(arr);
	// 然后开始随意交换,但是保证每个数距离不超过K
	// swap[i] == true, 表示i位置已经参与过交换
	// swap[i] == false, 表示i位置没有参与过交换
	boolean[] isSwap = new boolean[arr.length];
	for (int i = 0; i < arr.length; i++) {
		int j = Math.min(i + (int) (Math.random() * (K + 1)), arr.length - 1);
		if (!isSwap[i] && !isSwap[j]) {
			isSwap[i] = true;
			isSwap[j] = true;
			int tmp = arr[i];
			arr[i] = arr[j];
			arr[j] = tmp;
		}
	}
	return arr;
}

// for test
public static int[] copyArray(int[] arr) {
	if (arr == null) {
		return null;
	}
	int[] res = new int[arr.length];
	for (int i = 0; i < arr.length; i++) {
		res[i] = arr[i];
	}
	return res;
}

// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
	if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
		return false;
	}
	if (arr1 == null && arr2 == null) {
		return true;
	}
	if (arr1.length != arr2.length) {
		return false;
	}
	for (int i = 0; i < arr1.length; i++) {
		if (arr1[i] != arr2[i]) {
			return false;
		}
	}
	return true;
}

// for test
public static void printArray(int[] arr) {
	if (arr == null) {
		return;
	}
	for (int i = 0; i < arr.length; i++) {
		System.out.print(arr[i] + " ");
	}
	System.out.println();
}

// for test
public static void main(String[] args) {
	System.out.println("test begin");
	int testTime = 500000;
	int maxSize = 100;
	int maxValue = 100;
	boolean succeed = true;
	for (int i = 0; i < testTime; i++) {
		int k = (int) (Math.random() * maxSize) + 1;
		int[] arr = randomArrayNoMoveMoreK(maxSize, maxValue, k);
		int[] arr1 = copyArray(arr);
		int[] arr2 = copyArray(arr);
		sortedArrDistanceLessK(arr1, k);
		comparator(arr2, k);
		if (!isEqual(arr1, arr2)) {
			succeed = false;
			System.out.println("K : " + k);
			printArray(arr);
			printArray(arr1);
			printArray(arr2);
			break;
		}
	}
	System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}

} `