zoukankan      html  css  js  c++  java
  • 堆排序算法 java 实现

    堆排序算法 java 实现

    白话经典算法系列之七 堆与堆排序

    Java排序算法(三):堆排序

    算法概念

    堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。堆排序是不稳定的排序方法,辅助空间为O(1), 最坏时间复杂度为O(nlog2n) ,堆排序的堆序的平均性能较接近于最坏性能。

    算法思想

    1. 建立最小堆;

    2. 取出堆顶元素,顺序放到待排序数组中;将堆底元素放到堆顶,并重新调整堆;

    3. 重复步骤 2 ,直至堆中所有元素全部取完;


    参考的两篇文章都是将堆顶元素和堆底元素互换,最后存放堆的数组就变成了有序数组。

    1. 建立最大堆;
    2. 将堆顶元素和堆底元素互换;重新调整除堆底有序元素外的堆;
    3. 重复步骤 2 ,直至堆中全部元素都变有序;

    算法实现

    package com.lygedi.sort;
    
    import org.apache.commons.lang.ArrayUtils;
    import org.apache.commons.lang.StringUtils;
    
    public class HeapSort {
    	public static void main(String[] args) {
    		int a[] = { 49, 38, 65, 9, 76, 13, 27, 49, 8, 34, 12, 64, 49, 56, 2, 51, 13, 5, 4, 62, 99, 98, 54, 56, 17, 17,
    				18, 23, 34, 56, 15, 35, 25, 53, 51 };
    
    		int[] b = a.clone();
    		
    		HeapSort hs = new HeapSort();
    		hs.sortByMinHeapClass(a);
    		hs.sortByOneMothed(b);
    		
    		System.out.println(a.length);
    		for (int i = 0; i < a.length; i++)
    			System.out.println(Integer.toString(i) + "-" + a[i] + "--" + b[i]);
    	}
    	
    	public void sortByMinHeapClass(int[] list) {
    		MinHeap mh = new MinHeap(list);
    		System.out.println(mh);
    		for (int i = 0; i < list.length; i++) {
    			list[i] = mh.pushTop();
    		}
    	}
    	
    	public void sortByOneMothed(int[] list){
    		for(int i = list.length-1; i>=0; i--){
    			initMaxHeap(list,0,i);
    			swap(list,0,i);
    		}
    	}
    
    	private void initMaxHeap(int[] list,int startIndex,int stopIndex){
    		int leftChild, rightChild;
    		boolean isChanged = false;
    		
    		for(int i=startIndex;i<=stopIndex;i++){
    			leftChild = i*2 + 1;
    			rightChild = i*2 + 2;
    			
    			if(leftChild<=stopIndex && list[i]<list[leftChild]){
    				swap(list,i,leftChild);				
    				isChanged = true;
    			}
    			
    			if(rightChild<=stopIndex && list[i]<list[rightChild]){
    				swap(list,i,rightChild);	
    				isChanged = true;
    			}
    			
    			if(i>startIndex && isChanged){
    				i = (i - 1)/2 - 1;
    				isChanged = false;
    			}
    		}
    	}
    	
    	private void swap(int[] list,int i,int j){
    		int temp = list[i];
    		list[i] = list[j];
    		list[j] = temp;
    	}
    }
    
    class MinHeap {
    	private int[] heap;
    
    	public MinHeap(int[] list) {
    		heap = list;
    		fixHeap();
    	}
    
    	public int pushTop() {
    		int top = heap[0];
    		int tail = heap[heap.length - 1];
    
    		if (heap.length > 1) {
    			int[] newheap = ArrayUtils.subarray(heap, 0, heap.length - 1);
    			newheap[0] = tail;
    
    			heap = newheap;
    			fixHeap();
    		}
    
    		return top;
    	}
    	
    	private void swap(int[] list,int i,int j){
    		int temp = list[i];
    		list[i] = list[j];
    		list[j] = temp;
    	}
    
    	private void fixHeap() {
    		int leftChild, rightChild;
    		boolean isChanged = false;
    
    		for (int i = 0; i < heap.length; i++) {
    			leftChild = i * 2 + 1;
    			rightChild = i * 2 + 2;
    
    			if (leftChild <= heap.length - 1 && heap[i] > heap[leftChild]) {
    				swap(heap,i,leftChild);	
    				isChanged = true;
    			}
    
    			if (rightChild <= heap.length - 1 && heap[i] > heap[rightChild]) {
    				swap(heap,i,rightChild);
    
    				isChanged = true;
    			}
                //如果子节点进行了调整,则要对父节点重新进行调整
    			if (isChanged && i > 0) {
    				i = (i - 1) / 2 - 1;
    				isChanged = false;
    			}
    		}
    	}
    
    	public String toString() {
    		StringBuilder sb = new StringBuilder();
    		int count = heap.length;
    		int grade = (int) Math.ceil(java.lang.StrictMath.pow(count, 1.0 / 2));
    		
    		String padding = "**";
    
    		int index = 0;
    		for (int i = 1; i <= grade; i++) {
    			int padNum = (int)Math.pow(2, grade-i+1)-1;
    			String gradePadding = StringUtils.repeat(padding, padNum);
    			
    			for (int j = 1; j <= Math.pow(2, i - 1); j++) {
    				if (index < count) {
    					sb.append(gradePadding);
    					String paddingInt = StringUtils.leftPad(Integer.toString(heap[index]), padding.length(), "*");
    					sb.append(paddingInt);
    					index++;
    					sb.append(gradePadding);
    					sb.append(padding);
    				}
    			}
    			sb.append("
    
    
    ");
    		}
    
    		return sb.toString();
    	}
    }
    
  • 相关阅读:
    搭建CDH的yum本地源
    搭建一个离线yum源
    VMware主机 几次断电后,挂载的磁盘报错了,系统无法启动
    vm workstation15 迁移至ESXi6.7步奏
    ESXi6.7在 ASUS PRIME B360-PLUS 主板上安装报错
    php常用函数
    PHP函数
    php语句
    TSQL语句练习题
    php的基础
  • 原文地址:https://www.cnblogs.com/lygbzhu/p/5441835.html
Copyright © 2011-2022 走看看