当前位置:网站首页>handwritten big pile

handwritten big pile

2022-08-09 13:43:00 Love to knock code Harrison

用数组实现一个大根堆

实现功能
  • 每给一个数加进数组后,自动调整为大根堆结构(heapInsert()方法)
  • 返回大根堆中的最大值,并且在大根堆中把最大值删除,且剩下的数,依然保持为大根堆结构(heapify()方法)

自己手写一个大根堆结构 VS 纯暴力的方法,用对数器测试100万组!!!

package com.harrison.class04;

public class Code01_MaxHeap {
    
	public static class MyMaxHeap {
    
		private int[] heap;
		private final int limit;
		private int heapSize;

		public MyMaxHeap(int limit) {
    
			heap = new int[limit];
			heapSize = 0;
			this.limit = limit;
		}

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

		// 堆结构的两个关键操作:从某个位置开始往上看
		// 动态地建立大根堆
		// 如果收了N个数,时间复杂度为logN
		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 int pop() {
    
			int ans = heap[0];
			swap(heap, 0, --heapSize);
			heapify(heap, 0, heapSize);
			return ans;
		}

		// 堆结构的两个关键操作:从某个位置开始往下调,时间复杂度logN
		// heapSize 自己想象范围的大小,并不是数组的实际大小!!!
		public static void heapify(int[] arr, int index, int heapSize) {
    
			int left=(2*index)+1;
			while(left<heapSize) {
    
				int largest=(left+1<heapSize && arr[left+1]>arr[left])?left+1:left;
				int allLargest=arr[largest]>arr[index]?largest:index;
				if(allLargest==index) {
    
					break;
				}
				swap(arr, allLargest, index);
				index=allLargest;
				left=(2*index)+1;
			}
		}
		
		public boolean isEmpty() {
    
			return heapSize==0;
		}
		
		public boolean isFull() {
    
			return heapSize==limit;
		}
	}

	public static void swap(int[] arr, int i, int j) {
    
		int t = arr[i];
		arr[i] = arr[j];
		arr[j] = t;
	}
	
	public static class RightMaxHeap{
    
		private int[] arr;
		private int size;
		private final int limit;
		
		public RightMaxHeap(int limit) {
    
			this.limit=limit;
			arr=new int[limit];
			size=0;
		}
		
		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[maxIndex]<arr[i]) {
    
					maxIndex=i;
				}
			}
			int ans=arr[maxIndex];
			arr[maxIndex]=arr[--size];
			return ans;
		}
		
		public boolean isEmpty() {
    
			return size==0;
		}
		
		public boolean isFull() {
    
			return size==limit;
		}
	}
	
	public static void main(String[] args) {
    
		int testTimes=1000000;
		int limit=1000;
		int value=100;
		System.out.println("test begin");
		for(int i=0; i<testTimes; i++) {
    
			// [1,1000],防止出现零,否则一开始堆的大小就为0
			int curLimit=(int)(Math.random()*limit)+1;
			MyMaxHeap my=new MyMaxHeap(curLimit);
			RightMaxHeap test=new RightMaxHeap(curLimit);
			int curOopsTimes=(int)(Math.random()*limit);
			for(int j=0; j<curOopsTimes; 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+1));
					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+1));
						my.push(curValue);
						test.push(curValue);
					}else {
    
						if(my.pop()!=test.pop()) {
    
							System.out.println("Oops");
						}
					}
				}
			}
		}
		System.out.println("finish");
	}
}

原网站

版权声明
本文为[Love to knock code Harrison]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/221/202208091200373761.html