【数据结构】堆排序原理及实现
1.堆是一颗完全二叉树。
2.建立大根堆进行排序步骤
1)从第一个非叶子点开始堆化,一直到根节点
2)每次将根节点(最大值)放到最后面 重新堆化
/** * @Description:堆排 * @Author: cckong * @Date: */ public class heapsort { public static void main(String[] args) { int[] arr = {5, 3, 2, 6, 7, 8, 9, 10, 1, 12, 4, 21}; int len=arr.length; //从第一个非叶子节点开始堆化 一直到根节点 for(int i=len/2-1;i>=0;i--){ heapify(arr,i,len); } for(int tmp:arr) System.out.print(tmp+" "); //开始排序 for(int i=len-1;i>0;i--){ swap(arr,0,i);//将大根堆的根节点(目前的最大值) 放到当前最后一位 heapify(arr,0,i);//将剩余的结点重新堆化 长度减少1位 } System.out.println(); for(int tmp:arr) System.out.print(tmp+" "); } /** * @Description: 堆化操作 * @Param: 建堆数组arr 开始堆化的位置i 最大长度len * @return: null * @Author: cckong * @Date: 2021/4/12 */ public static void heapify(int[] arr,int i,int len){ int tmp=arr[i]; //注意for循环条件 从根的左子开始 每次都要去子的子结点(孙子结点)所以是k=2k+1 for(int k=2*i+1;k<len;k=2*k+1){ if(k+1<len&&arr[k+1]>arr[k]) k++;//父 左子 右子 在左右子选出最大的那个变为新父节点 if(arr[k]>arr[i]){ arr[i]=arr[k];//将当前i值替换成k值 i=k;//i变k继续向下堆化 }else {break;} } arr[i]=tmp;//最后一步进行赋值 } /** * @Description: 交换函数 * @Param: 需要排序的数组arr 交换的位置 i j * @return: null * @Author: cckong * @Date: 2021/4/12 */ public static void swap(int[] arr,int i,int j){ int tmp=arr[i];arr[i]=arr[j];arr[j]=tmp; } }
3.小根堆只要改上面堆化的大于号改为小于号
/** * @Description: 堆化操作 * @Param: 建堆数组arr 开始堆化的位置i 最大长度len * @return: null * @Author: cckong * @Date: 2021/4/12 */ public static void heapify(int[] arr,int i,int len){ int tmp=arr[i]; //注意for循环条件 从根的左子开始 每次都要去子的子结点(孙子结点)所以是k=2k+1 for(int k=2*i+1;k<len;k=2*k+1){ if(k+1<len&&arr[k+1]<arr[k]) k++;//父 左子 右子 在左右子选出最大的那个变为新父节点 if(arr[k]<arr[i]){ arr[i]=arr[k];//将当前i值替换成k值 i=k;//i变k继续向下堆化 }else {break;} }