堆排序的思想
利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。
其基本思想为(大顶堆):
1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;
2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
操作过程如下:
1)初始化堆:将R[1..n]构造为堆;
2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。
package sort; import java.util.Scanner; public class 堆排 { static void maxHeapity(int a[],int x,int y){//保持最大堆性质 int max=a[x]; int l=x; if (((x+1)*2<y)&&(a[(x+1)*2]>max) ) { l=(x+1)*2; max=a[l]; } if ((x*2+1<y)&&(a[x*2+1]>max) ){ l=x*2+1; max=a[l]; } if (l!=x){ int t; t=a[l];a[l]=a[x];a[x]=t; maxHeapity(a,l,y); } } static void buildMaxHead(int a[],int n){//建堆 int i; for (i=n/2;i>=0;i--) maxHeapity(a,i,n); } public static void main(String[] args) { Scanner read = new Scanner(System.in); //System.out.println("输入元素个数N:="); int n=read.nextInt(); int a[]=new int[n]; int b[]=new int[n]; int i; for ( i=0;i<n;i++) a[i]=read.nextInt(); buildMaxHead(a,n); int l=n; for(i=0;i<l;i++) { b[i]=a[0]; a[0]=a[n-1]; n=n-1; maxHeapity(a,0,n); } for (i=0;i<l;i++) System.out.print(b[i]+" "); } }
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法package sort; import java.util.Scanner; public class 二分排序 { private static int sort(int a[],int x,int y ){ if (x==y) return 0; int mid=(x+y)/2; sort(a,x,mid); sort(a,mid+1,y); int l=x; int r=mid+1; int b[]=new int[y-x+1]; int s=0;int t; while ((l<=mid)&&(r<=y)){ if (a[l]>a[r]) { b[s]=a[r];r++; } else {b[s]=a[l];l++;} s++; } if (l<=mid) for (int i=l;i<=mid;i++) {b[s]=a[i];s++;} else for (int i=r;i<=y;i++) {b[s]=a[i];s++;} for (int i=0;i<s;i++) a[x+i]=b[i]; return 0; } public static void main(String[] args) { Scanner read = new Scanner(System.in); //System.out.println("输入元素个数N:="); int n=read.nextInt(); int a[]; a=new int[n]; for (int i=0;i<n;i++) a[i]=read.nextInt(); int l=sort(a,0,n-1); for (int i=0;i<n;i++) System.out.print(a[i]+" "); } }
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
package sort; import java.util.Scanner; public class 快排 { private static void sort(int x,int y,int[] a){ int i,j,k,t,l; i=x; j=y; l=(i+j)/2; k=a[l]; do{ System.out.print(i+" "+j+" "+k+"------"); while ( (i<j) && (a[i]<k)) { i++;} while ( (i<j) && (a[j]>k) ) { j--;} System.out.println(i+" "+j+" "+k); if (i<j) { if (a[i]==k ) l=j; if (a[j]==k) l=i; t=a[i]; a[i]=a[j];a[j]=t; i++; j--; } }while (i<j); if (l-1>x) { sort(x,l-1,a); } if (l+1<y) { sort(l+1,y,a); } } public static void main(String[] args) { Scanner read = new Scanner(System.in); //System.out.println("输入元素个数N:="); int n=read.nextInt(); int a[]; a=new int[n]; for (int i=0;i<n;i++) a[i]=read.nextInt(); sort(0,n-1,a); for (int i=0;i<n;i++) System.out.print(a[i]+" "); } }
时间: 2024-10-17 16:30:06