BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #52889同步于 2016/9/13
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

[问题]堆排序,数组越界,求指点

ywq956283501
2016/9/13镜像同步7 回复
package com.package5; public class HeapSort { public static void main(String[] args) { int[] arr={10,50,30,20,60,80,70,90,40}; System.out.println(arr.length/2); HSort(arr); //进行排序 for(int i:arr) System.out.println(i); } public static void HSort(int[] a){ int i; for(i=a.length/2;i>0;i--){ MaxHeap(a,i,a.length); //构建大顶堆 } for(i=a.length;i>1;i--){ swap(a,1,i);//将堆顶纪录和当前未排序子序列的最后一个纪录交换 MaxHeap(a, 1, i-1); //将a[]数组其余部分重新调整为大顶堆 } } public static void swap(int[] a, int i, int j) { int temp=a[i]; a[i]=a[j]; a[j]=temp; } public static void MaxHeap(int[] a, int s, int m) { int temp,j; temp=a[s]; for(j=2*s;j<=m;j*=2){ //沿关键字较大的孩子节点向下筛选 if(j<m&&a[j]<a[j+1]){ //!!!!!!!!报 java.lang.ArrayIndexOutOfBoundsException ++j; //j为关键字中较大纪录的下标 } if(temp>=a[j]){ break; } a[s]=a[j]; s=j; } a[s]=temp; //插入数据 } } [ema1][ema1][ema1][ema1][ema1]
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
byrEE机器人#1 · 2016/9/13
public class HeapSort { public static void main(String[] args) { int[] arr={10,50,30,20,60,80,70,90,40}; //System.out.println(arr.length/2); HSort(arr); //进行排序 for(int i:arr) System.out.println(i); } public static void HSort(int[] a){ int i; for(i=a.length/2;i>=0;i--){ MaxHeap(a,i,a.length-1); //构建大顶堆【数组越界,应该length-1,不清楚你这个参数是不是】 } for(i=a.length-1;i>0;i--){ //【还是数组越界问题,length-1】 swap(a,1,i);//将堆顶纪录和当前未排序子序列的最后一个纪录交换 MaxHeap(a, 1, i-1); //将a[]数组其余部分重新调整为大顶堆 } } public static void swap(int[] a, int i, int j) { int temp=a[i]; a[i]=a[j]; a[j]=temp; } public static void MaxHeap(int[] a, int s, int m) { int temp,j; temp=a[s]; for(j=2*s;j<m;j*=2){ //沿关键字较大的孩子节点向下筛选 if(j<m && a[j]<a[j+1]){ //【既然有j+1,那么j+1也应该小于等于m,所以j<m】 ++j; //j为关键字中较大纪录的下标 } if(temp>=a[j]){ break; } a[s]=a[j]; s=j; } a[s]=temp; //插入数据 } } 不过输出结果还是不大对,没太看明白你是怎么堆排的 我一般是建堆,对里边做堆调整,最后堆排 又改了下,你的用例过了,我的没有。。。 public class HeapSort { public static void main(String[] args) { int[] arr={2,9,6,3,5,8,5,2,1,4,6,3,6,9,5,22,55,6,4,5,6,26,29,6,2,9,95,58,45,47,46,25,26,36,62}; //System.out.println(arr.length/2); int[] arr2={10,50,30,20,60,80,70,90,40}; HSort(arr); //进行排序 HSort(arr2); //swap(arr,0,1); for(int i:arr) System.out.print(i+" "); System.out.println(); for(int i:arr2) System.out.print(i+" "); System.out.println(); } public static void HSort(int[] a){ int i; for(i=a.length/2;i>0;i--){ MaxHeap(a,i,a.length-1); //构建大顶堆 } for(i=a.length-1;i>0;i--){ swap(a,1,i);//将堆顶纪录和当前未排序子序列的最后一个纪录交换 MaxHeap(a, 1, i-1); //将a[]数组其余部分重新调整为大顶堆 } } public static void swap(int[] a, int i, int j) { int temp=a[i]; a[i]=a[j]; a[j]=temp; } public static void MaxHeap(int[] a, int s, int m) { int temp,j; temp=a[s]; for(j=2*s;j<=m;j*=2){ //沿关键字较大的孩子节点向下筛选 if(j<m && a[j]<a[j+1]){ //!!!!!!!!报 java.lang.ArrayIndexOutOfBoundsException ++j; //j为关键字中较大纪录的下标 } if(temp>=a[j]){ break; } a[s]=a[j]; s=j; } a[s]=temp; //插入数据 } } 这是我的代码 public class HeapSort{ public void heapAdjust(int[] arr,int i,int size){ int left=2*i+1; //left node int right=2*i+2; //right node int largest=i; if(left<size && arr[i]<arr[left]) largest=left; if(right<size && arr[right]>arr[largest]) largest=right; if(largest!=i){ tmp=arr[i]; arr[i]=arr[largest]; arr[largest]=tmp; heapAdjust(arr,largest,size); } } public void buildHeap(int[] arr,int size){ for(int i=size/2-1;i>=0;i--) heapAdjust(arr,i,size); } public void heapSort(int[] arr){ int size=arr.length; buildHeap(arr,size); for(int i=size-1;i>=0;i--){ tmp=arr[0]; arr[0]=arr[i]; arr[i]=tmp; heapAdjust(arr,0,i); } } public static void main(String[] args){ int[] arr={2,9,6,3,5,8,5,2,1,4,6,3,6,9,5,22,55,6,4,5,6,26,29,6,2,9,95,58,45,47,46,25,26,36,62}; HeapSort hs=new HeapSort(); hs.heapSort(arr); for(int i=0;i<arr.length;i++) System.out.print(arr[i]+" "); System.out.println(); } }
mrcuber机器人#2 · 2016/9/13
访问a[j+1]越界了,打印几次试试呗
byrEE机器人#3 · 2016/9/13
那个我也以为是一个问题,但是试了下反而没问题,关键是他的数组 都是 length 开始swap,这个肯定越界 【 在 mrcuber 的大作中提到: 】 : 访问a[j+1]越界了,打印几次试试呗
ml3615556机器人#4 · 2016/9/13
数组下标从0开始,到length - 1结束 堆排序建议还是写sink + swim,野路子自己写写就好。。
ywq956283501机器人#5 · 2016/9/13
sink + swim 是什么意思?[ema1]求老司机解释解释 【 在 ml3615556 的大作中提到: 】 : 数组下标从0开始,到length - 1结束 : 堆排序建议还是写sink + swim,野路子自己写写就好。。
ml3615556机器人#6 · 2016/9/13
sink与swim都是为了保持堆有序的算法,顾名思义,一个上浮一个下沉 http://m.blog.csdn.net/article/details?id=47058121 【 在 ywq956283501 的大作中提到: 】 : sink + swim 是什么意思?求老司机解释解释
tingxuelouwq机器人#7 · 2016/9/13
建议你调试一下,这样能够更清楚的知道问题出在哪,也能知道你这么写的思想。而且,你发现没,你对数组的排序都是从下标为1开始的,那下标为0的元素不就懵逼了。 public static void main(String[] args) { int[] a = {10,50,30,20,60,80,70,90,40}; buildHeap(a); for(int i = 0; i < a.length; i++) System.out.print(a[i] + " "); } public static void buildHeap(int[] a) { for(int i = a.length / 2; i >= 0; i--) percDown(a, i, a.length); for(int i = a.length - 1; i > 0; i--) { swap(a, 0, i); percDown(a, 0, i); } } private static void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } private static void percDown(int[] a, int i, int n) { int child,tmp; for(tmp = a[i]; leftChild(i) < n; i = child) { child = leftChild(i); if(child != n - 1 && a[child] < a[child + 1]) child++; if(tmp < a[child]) a[i] = a[child]; else break; } a[i] = tmp; } private static int leftChild(int i) { return 2 * i + 1; } 【 在 ywq956283501 的大作中提到: 】 : package com.package5; : public class HeapSort { : public static void main(String[] args) { : ...................