java实现堆排序算法

算法之堆排

算法虐我千百遍,我爱算法如初恋(微笑)

研究堆排序也是一脸懵逼,所以我决定好好分析一下,尽量白话一点,方便理解。

总的来说就是一个二叉树结构1-2-4-8……这样的,从左至右排,最后一排排不满就不管了。我先以我给的数组为例18,11,9,7,3,4,2,2,3,9 从第一个开始的序号是0最后一个是heapSize-1.

整个算法最关键的点就是保证每个三角形结构,三角形顶尖是最大的,左右谁大谁小在递归的时候就自己排好了。既然要开始选择三角形了,那么就从序号最大的开始,毕竟什么事都要从基层做起嘛~

我称三角形顶尖的数为小弟1和小弟2的老大,那最大序号的老大是多少呢?(heapSize-2)/ 2 由于是整数,不管三角形是缺了一角还是没缺,除不尽反正就四舍了。

那三个数比大小还不简单~谁大谁就是老大嘛

 int left = left(i);   
int right = right(i);   
int parent = i;
if(left < heapSize && a[left] > a[parent]) {   //
parent = left;
}
if(right < heapSize && a[right] > a[parent])  
{
parent = right;
}

那旧老大被新老大顶替了,还要看看下面小弟要不要造反,以此往复就成了递归,那我们程序加入递归:

 int left = left(i);   
        int right = right(i);   
        int parent = i;
        if(left < heapSize && a[left] > a[parent]) {   //
            parent = left;
        }
        if(right < heapSize && a[right] > a[parent])  
        {
            parent = right;
        }
        if(parent != i) {      
            int temp = a[parent];
            a[parent]=a[i];
            a[i]=temp;
            maxHeapfy(a,parent,heapSize);    
        }

那最大序号做完了,这小弟们造反不是要一起吗,我们让每个父节点都要遍历一遍,那就是刚才的(heapSize-2)/ 2往下减一,我这么不知道你思路清晰了一点没,下面是我的完整代码。

package suanfa.test;

import java.util.Arrays;
/**
 * 
 * @author Tacenee
 *
 */
public class DuiPai {

    static int left(int i) {
        return 2*i + 1;
    }
    static int right(int i) {
        return 2*i + 2;
    }
    /**
     * 
     * @param a 数组a
     * @param i 第i个结点
     * @param heapSize heapSize是数组种实际要排序的元素的长度
     */
    static void maxHeapfy(int []a,int i,int heapSize) { 
        int left = left(i);   
        int right = right(i);   
        int parent = i;
        //判断是否还有子结点
        if(left < heapSize && a[left] > a[parent]) {   //
            parent = left;
        }
        if(right < heapSize && a[right] > a[parent])  
        {
            parent = right;
        }
        //将三者最大值跟父节点调换,但是不考虑左右子结点谁大谁小
        if(parent != i) {      
            int temp = a[parent];
            a[parent]=a[i];
            a[i]=temp;           
            //当换了爸爸以后,看被换掉的儿子的儿子是不是也要换
            maxHeapfy(a,parent,heapSize);    
        }
    }
    static void buildMaxHeap(int []a,int heapSize) {
        for(int i = (heapSize-2)/2;i >= 0;i--) {
            maxHeapfy(a,i,heapSize);
        }
    }
    static void heapSort(int []a) {
    	 int len = a.length-1;
    	 //初始化堆
         buildMaxHeap(a,len);
         
         for(int i =len;i>0;i--) {
        	 //对调最大的和最后一个结点
        	 int temp =a[0];
             a[0]=a[len];
             a[len]=temp;  
             len--;
             //最大值已确定,总长度减1迭代
             maxHeapfy(a,0,len);
         }
      
    }
    
	 public static void main(String args[]) {
		 int []a = {18,11,9,7,3,4,2,2,3,9};
	        heapSort(a);
	        System.out.println(Arrays.toString(a));
	    }
	 
	 
}
//结果:[2, 2, 3, 3, 4, 7, 9, 9, 11, 18]

**如有不足还望指点,多谢

猜你喜欢

转载自blog.csdn.net/TangXiaoPang/article/details/87896297
今日推荐