堆排序JAVA实现
2017-06-05 15:35
253 查看
首先说明,这个堆排序是百度百科的JAVA实现版本,但是这个版本有几处错误,所以我在这里补充一下,下面贴上修改后的代码,标红色的就是修改后的地方
public class HeapSort {
private static int[] sort=new int[]{1,0,10,20,3,5,6,4,9,8,12,17,34,11};
//private static int[] sort=new int[]{1,2,3,4,5,6,9,7,21};
public static void main(String args[]){
buildMaxHeapify(sort);
heapSort(sort);
print(sort);
}
private static void buildMaxHeapify(int[] data){
int startIndex=getParentIndex(data.length-1);
for(int i=startIndex;i>=0;i--)
maxHeapify(data,data.length-1,i);
}
//创建最大堆
private static void maxHeapify(int[] data,int heapSize,int index){
int left=getChildLeftIndex(index);
int right=getChildRightIndex(index);
//倒数第二个数必须比倒数第一个大数据才正确,但是这里改成<=时候,前面数据正确,但是后面又出问题了
int largest=index;
//原本版是if(left<heapSize&&data[index]<data[left]),没有等于号
if(left<=heapSize&&data[index]<data[left])
largest=left;
if(right<=heapSize&&data[largest]<data[right])
largest=right;
//得到最大值后可能需要先交换,如果交换不了,其子结点可能就不是最大堆了,需要重新调整
if(largest!=index){
int temp=data[index];
data[index]=data[largest];
data[largest]=temp;
maxHeapify(data,heapSize,largest);
}
System.out.println("--------------");
print(data);
System.out.println("--------------");
}
//排序,最大值放在末尾,data虽然是最大堆,在排序后就成了递增的
private static void heapSort(int[] data){
System.out.println("开始排序~~~~~~");
//末尾与头交换,交换后调整最大堆
for(int i=data.length-1;i>0;i--){
int temp=data[0];
data[0]=data[i];
data[i]=temp;
//原版本是maxHeapify(data,i,0);
maxHeapify(data,i-1,0);
}
}
private static int getParentIndex(int current){
return (current-1)>>1;
}
private static int getChildLeftIndex(int current){
return (current<<1)+1;
}
private static int getChildRightIndex(int current){
return (current<<1)+2;
}
private static void print(int[] data){
int pre=-2;
for(int i=0;i<data.length;i++){
if(pre<(int)getLog(i+1)){
pre=(int)getLog(i+1);
System.out.println();
}
System.out.println(data[i]+"|");
}
}
private static double getLog(double param){
return Math.log(param)/Math.log(2);
}
}
首先原版本堆排序是错误的,只有倒数第一个不是最大的数的时候,原版本才是正确的。
因为没有等于号,所以每次判断,都没有判断最后一个元素。
此外,原版本是i,这样其实重复多执行了一次,所以修改成i-1,并且只有修改成i-1后,if(left<=heapSize&&data[index]<data[left])这条语句才算正确,否则就会错误地把最后一个元素也算进排序中,这样就排序出错了,可能解释的不太清楚,之后再详细修改。现在先就指出百度百科这两个错误的地方
public class HeapSort {
private static int[] sort=new int[]{1,0,10,20,3,5,6,4,9,8,12,17,34,11};
//private static int[] sort=new int[]{1,2,3,4,5,6,9,7,21};
public static void main(String args[]){
buildMaxHeapify(sort);
heapSort(sort);
print(sort);
}
private static void buildMaxHeapify(int[] data){
int startIndex=getParentIndex(data.length-1);
for(int i=startIndex;i>=0;i--)
maxHeapify(data,data.length-1,i);
}
//创建最大堆
private static void maxHeapify(int[] data,int heapSize,int index){
int left=getChildLeftIndex(index);
int right=getChildRightIndex(index);
//倒数第二个数必须比倒数第一个大数据才正确,但是这里改成<=时候,前面数据正确,但是后面又出问题了
int largest=index;
//原本版是if(left<heapSize&&data[index]<data[left]),没有等于号
if(left<=heapSize&&data[index]<data[left])
largest=left;
if(right<=heapSize&&data[largest]<data[right])
largest=right;
//得到最大值后可能需要先交换,如果交换不了,其子结点可能就不是最大堆了,需要重新调整
if(largest!=index){
int temp=data[index];
data[index]=data[largest];
data[largest]=temp;
maxHeapify(data,heapSize,largest);
}
System.out.println("--------------");
print(data);
System.out.println("--------------");
}
//排序,最大值放在末尾,data虽然是最大堆,在排序后就成了递增的
private static void heapSort(int[] data){
System.out.println("开始排序~~~~~~");
//末尾与头交换,交换后调整最大堆
for(int i=data.length-1;i>0;i--){
int temp=data[0];
data[0]=data[i];
data[i]=temp;
//原版本是maxHeapify(data,i,0);
maxHeapify(data,i-1,0);
}
}
private static int getParentIndex(int current){
return (current-1)>>1;
}
private static int getChildLeftIndex(int current){
return (current<<1)+1;
}
private static int getChildRightIndex(int current){
return (current<<1)+2;
}
private static void print(int[] data){
int pre=-2;
for(int i=0;i<data.length;i++){
if(pre<(int)getLog(i+1)){
pre=(int)getLog(i+1);
System.out.println();
}
System.out.println(data[i]+"|");
}
}
private static double getLog(double param){
return Math.log(param)/Math.log(2);
}
}
首先原版本堆排序是错误的,只有倒数第一个不是最大的数的时候,原版本才是正确的。
因为没有等于号,所以每次判断,都没有判断最后一个元素。
此外,原版本是i,这样其实重复多执行了一次,所以修改成i-1,并且只有修改成i-1后,if(left<=heapSize&&data[index]<data[left])这条语句才算正确,否则就会错误地把最后一个元素也算进排序中,这样就排序出错了,可能解释的不太清楚,之后再详细修改。现在先就指出百度百科这两个错误的地方
相关文章推荐
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 自主实现的Java实现的构造大小堆、堆排序的算法
- 堆排序详解以及java实现
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 最大堆及堆排序的Java实现_world
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- [原]堆排序的java实现
- [转载]堆排序(HeapSort) Java实现
- 【转】排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- java 实现堆排序
- 算法导论Java实现-堆排序(6.4章节)
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 堆排序(java实现)
- 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序
- Java实现快速排序、归并排序、堆排序
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- heapsort堆排序(3种语言实现 c/java/python)
- 堆排序及其JAVA实现