堆排序

来源:互联网 发布:kik软件 编辑:程序博客网 时间:2024/06/08 01:21

1. 堆是一种完全二叉树 但是与普通的完全二叉树不同 特点:

  ① 最大堆:父结点的键值比左右孩子的键值大

   ② 对于堆中任意一个节点开始 其子堆还是完全的二叉堆


2. 要点:

    ① 根据 给定的初始数组 建立一个初始堆(从最后一个非叶子结点(数组中索引N/2位置)的值上滤进行调整) 调整的方式 每一次从其左孩子、右孩子和父节点 选择最大的值进行交换 当对堆进行调整形成初始堆。

    ②接下来开始进行堆得排序 排序过程:将堆顶元素与堆最后一个元素进行交换 输出最后一个元素最后调整堆相当于对堆得删除操作。

总结:堆排序 第一步建立初始堆 第二步进行堆顶与堆未元素进行交换 交换之后进行堆得调整,调整策略一样采用向下过滤方式。

package com.offerr;import java.util.ArrayList;public class HeapSort<AnyType> {@SuppressWarnings("rawtypes")public static <AnyType extends Comparable<? super AnyType>> ArrayList  heapSort(AnyType [] a){ArrayList<AnyType> array=new ArrayList<AnyType>();/*buildHeap*/for(int i=a.length/2-1;i>=0;i--)percDown(a,i,a.length);/*heapSort 调换堆首末元素 最后在重新调整堆 */for(int i=a.length-1;i>=0;i--){swap(a,0,i);array.add(a[i]);percDown(a, 0, i);}for(int i=0;i<array.size();i++)System.out.println(array.get(i)+" ");return array;}private static <AnyType> void swap(AnyType[] a, int i, int i2) {AnyType tmp=a[i];a[i]=a[i2];a[i2]=tmp;}private static <AnyType extends Comparable<? super AnyType>> void percDown(AnyType[] a, int i, int length) {int child=leftChild(i);AnyType tmp;/* * 从 左 右 父 挑选最大值 进行交换*/for(tmp=a[i];leftChild(i)<length;i=child){child=leftChild(i);if(child!=length-1 && a[child].compareTo(a[child+1])<0)child++;if(tmp.compareTo(a[child])<0)a[i]=a[child];elsebreak;}a[i]=tmp;}private static int leftChild(int i){return  2*i+1;}public static void main(String[] args){Integer[] array={5,11,7,2,3,17};heapSort(array);}}


最后添加一下,其他排序算法:

package com.offerr;public class EightSort {public static void MergeSort(int a[],int first,int last,int temp[]){if(first<last){int mid=(first+last)/2;MergeSort(a, first, mid, temp);MergeSort(a, mid+1, last, temp);// 分解成 基本单序列 进行合并Merge(a,first,mid,last,temp);}}private static void Merge(int[] a, int first, int mid, int last, int[] temp) {int i=first,j=mid+1;int m=mid,n=last;int k=0;while(i<=m && j<=n){if(a[i]<=a[j])temp[k++]=a[i++];elsetemp[k++]=a[j++];}while(i<=m)temp[k++]=a[i++];while(j<=n)temp[k++]=a[j++];//回复给原矩阵中for(i=0;i<k;i++)a[first+i]=temp[i];}public static void Print(int [] a){for(int i=0;i<a.length;i++)System.out.print(a[i]+" ");System.out.println();}public static void HeapSort(int [] a){/**建立一个初始堆*/for(int i=a.length/2-1;i>=0;i--)perDown(a,i,a.length);// 删除 for(int i=a.length-1;i>0;i--){int temp=a[0];a[0]=a[i];a[i]=temp;perDown(a, 0, i);}Print(a);}private static void perDown(int[] a, int s, int len) {int child;int temp;for(temp=a[s];(child=2*s+1)<len;s=child){child=2*s+1;if(child!=len-1 && a[child]>a[child+1])  // 挑选 两者中 最大值 与父结点进行比较 删除最大堆 ,最小堆的话 应该是 其中最小值child++;if(temp>a[child])// 删除最大堆,抛出 最大值存储在末尾a[s]=a[child];                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            elsebreak;}a[s]=temp;}public static void main(String[] args){int a[]={81,94,11,96,12,35};RadixSort(a, 2);Print(a);}/** * 基数排序:按照 个,十,百 位 排序,每一个 Pos 都有分配 和收集过程 * */public static void RadixSort(int [] a,int d){// array[i][0] 二维数组 记录第 i 行 数据个数 位数相同 在本桶中数个数 array存放每一次位数分配 存放数据int [][]array=new int[10][a.length+1];for(int i=0;i<10;i++)array[i][0]=0;for(int pos=1;pos<=d;pos++){// 将 数据按照 个,十,百 进行分配,位数相同 分配到同一个桶中for(int i=0;i<a.length;i++){int row=getNumInPos(a[i],pos);int col=++array[row][0];array[row][col]=a[i];}// 收集for(int row=0,i=0;row<10;row++){for(int col=1;col<=array[row][0];col++)a[i++]=array[row][col];array[row][0]=0;}}}private static int getNumInPos(int n, int pos) {int temp=1;for(int i=0;i<pos-1;i++)temp*=10;return (n/temp)%10;}}