1.Java实现各种排序
来源:互联网 发布:js 全局变量 丢失属性 编辑:程序博客网 时间:2024/06/04 19:47
下文是根据《算法-第四版》编写的排序代码,与大话数据结构中可能有出入,但思想是一样的,灵活多变的算法呀!
package com.yuan;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.Arrays;import java.util.Collections;import java.util.List;import java.util.Random;import java.util.Scanner;public class Selection { //-------------------------------------几种排序方法-------------------------------------// private static Comparable[] aux;//归并排序需要的辅助数组 //选择排序 1.基本思想:从数组的第一个元素开始,对数组中的每一个元素都执行——与后面的元素一一比较,记录元素值最小的索引下标,一开始将当前元素的下表设为min,与后面所有元素比较完毕以后,可以得到最小值的小标,然后交换最小值和当前元素。 2. 时间复杂度 public static void sort_Selection(Comparable[] a){ int N=a.length; for(int i=0;i<N;i++){ int min=i; for(int j=i+1;j<N;j++){ if(less(a[j],a[min])) min=j; } exch(a,i,min); } } //插入排序 1.基本思想:对数组中从第二项往后的每一项元素,执行——比较它与前面的元素的大小,前面的元素中比当前元素大的就往后移动一位,一直到比它小,此时j指向比当前元素小的那个位置,所以要把当前元素插入在a[j+1]处。 public static void sort_Insertion(Comparable[] a){ int N=a.length; int i,j; for(i=1;i<N;i++){ Comparable temp=a[i]; for(j=i-1;j>=0 && less(temp,a[j]); j--){ a[j+1]=a[j]; } a[j+1]=temp; } } //希尔排序 1.基本思想:插入排序的升级版,插入排序是当前元素和它前面的元素一个一个的比较,希尔排序是与每间隔h的元素才比较 大致有序---->全部有序,元素移动次数更少,效率更高 h的变化:从一个比较大的值,每排序一次,就变为h/3,缩小间隔。最后一次排序的间隔应该是1. public static void sort_Shell(Comparable[] a){ int N=a.length; int h=1; while(h<N/3) h = 3*h+1; while(h>=1) { //将数组变为h有序 int i,j; for(i=h; i<N; i++){ Comparable temp=a[i]; for(j=i-h; j>=h && less(temp,a[j]);j-=h){ a[j+h]=a[j]; } a[j+h]=temp; } h=h/3; } } //自顶向下的归并排序 1.基本思想:将整个数组从中间分成两块,然后再分别对分裂后的两块也执行从中间分裂的操作,一直循环直到一个块只包含一个元素,就返回上一层,执行右半边的sort()函数,发现也不能再分裂了,又返回,接着执行merge函数将数组的前两个元素合并(合并的过程就是排序的过程,这里需要申请另外一个相等的数组内存空间,用于存放原数组的备份,排序后依次存放在原数组中),第一次合并后sort执行完毕返回到上一层,接着执行右半边的sort(),对第三、四个元素排序合并,返回执行1234元素的合并操作...以此递归,直到返回到第一层,数组排序完毕。 2.merge函数:4个参数(数组a,要合并的数组的头、界限、尾),从两个数组的第一个元素开始比较,交叉尽心个,小的就放在数组a[]中,且对应的指针向后移动继续比较。如果其中一个数组先比较完,则把另一个数组剩余的元素依次添加到数组a[]的后面。 public static void sort_Merg(Comparable[] a){ aux= new Comparable[a.length]; sort(a,0,a.length-1); } public static void merge(Comparable[] a, int lo, int mid, int hi){ //原地归并的抽象方法 int i=lo, j=mid+1; for(int k=lo; k<=hi;k++) aux[k]=a[k]; for(int k=lo; k<=hi;k++) { if(i>mid) a[k]=aux[j++]; else if(j>hi) a[k]=aux[i++]; else if(less(aux[j],aux[i])) a[k]=aux[j++]; else a[k]=aux[i++]; } } private static void sort(Comparable[] a, int lo, int hi){ //归并排序的sort方法 if(hi<=lo) return; int mid=lo+(hi-lo)/2; sort(a,lo,mid); sort(a,mid+1,hi); merge(a,lo,mid,hi); } //自底向上的归并排序 1.基本思想:与自顶向下相反的是,从单独的一个元素开始执行合并操作,而不是首先对整个数组进行分裂。 合并尺寸:一开始是将两个元素合并在一起,所以合并尺寸是1,合并后数组大小变为2,所以下一次的合并尺寸是2倍的。 从第一个元素开始,两两合并for(int lo=0; lo<N-sz; lo=lo+2*sz) merge(a,lo,lo+sz-1,Math.min(lo+2*sz-1,N-1)); public static void sort_MergeBU(Comparable[] a){ int N=a.length; aux= new Comparable[N]; for(int sz=1; sz<N; sz=sz*2){ for(int lo=0; lo<N-sz; lo=lo+2*sz){ merge(a,lo,lo+sz-1,Math.min(lo+2*sz-1,N-1)); } } } //快速排序 1.基本思想:首先从数组中随机挑选一个元素值作为衡量标准,从数组的两端开始,使用两个指针(i和j),一个从头部开始,一个从尾部开始。 循环直到从头部的指针指向的元素比当前元素大,从尾部的指针指向的元素比当前元素小,那么交换这两个元素。一直到i>=j时说明整个数组全都比较完毕。 最后需要将当前元素放到合适的位置上。 public static void sort_Quick(Comparable[] a){ //List<Comparable> list = Arrays.asList(a); //Collections.shuffle(list); //a=(Comparable[]) list.toArray(); String s = sortQ(a,0,a.length-1); System.out.printf(s+"\n"); } private static String sortQ(Comparable[] a, int lo, int hi){ int M=50; if(hi<=lo+M){ sort_Insertion(a); return "使用的是插入排序!"; } int j=partition(a,lo,hi); sortQ(a,lo,j-1); sortQ(a,j+1,hi); return "使用的是快速排序!"; } private static int partition(Comparable[] a, int lo, int hi) { // TODO Auto-generated method stub int i=lo,j=hi+1; Comparable v=a[lo]; while(true){ while(less(a[++i],v)) if(i==hi) break; while(less(v,a[--j])) if(j==lo) break; if(i>=j) break; exch(a,i,j); } exch(a,lo,j); return j; } //--------------------------------------------通用方法--------------------------------------// //比较两元素大小 private static boolean less(Comparable v, Comparable w){ return v.compareTo(w)<0; } //交换两个元素 private static void exch(Comparable[] a, int i, int j){ Comparable t=a[i]; a[i]=a[j]; a[j]=t; } //显示数组内容 private static void show(Comparable[] a){ for(int i=0;i<a.length;i++){ System.out.println(a[i]+" "); } System.out.println("\n"); } //判断是否已经排序 public static boolean isSorted(Comparable[] a){ for(int i=1;i<a.length;i++) if(less(a[i],a[i-1])) return false; return true; } //主函数 public static void main(String[] args) { // TODO Auto-generated method stub Comparable[] a; System.out.printf("请输入数组长度N:\n"); Scanner sc = new Scanner(System.in); int n = sc.nextInt(); a=new String[n]; System.out.printf("请输入一个长度为%d的字符串数组,BufferedReader以换行区为标志区分不同的元素:\n",n); for(int i=0;i<n;i++){ //System.out.println("请输入:"); InputStream input = System.in; BufferedReader buf = new BufferedReader(new InputStreamReader(input)); String str = null; try { str = buf.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } a[i] = str; } //String[] a=new String[]{"a","c","d","g","b"}; //Integer[] a=new Integer[]{5,10,3,6,1,20,11,35,26}; //sort_Selection(a); //sort_MergeBU(a); //sort_Insertion(a); sort_Quick(a); isSorted(a); show(a); }}//比较两种排序算法的时间复杂度package com.compare;import java.util.Random;import com.yuan.Selection;public class SortCompare { public static long time(String alg, Long[] a){ long t1=System.currentTimeMillis(); if(alg.equals("sort_Insertion")) Selection.sort_Insertion(a); if(alg.equals("sort_Selection")) Selection.sort_Selection(a); if(alg.equals("sort_Shell")) Selection.sort_Shell(a); if(alg.equals("sort_Merg")) Selection.sort_Merg(a); if(alg.equals("sort_MergeBU")) Selection.sort_MergeBU(a); long t2=System.currentTimeMillis(); return t2-t1; } public static long timeRandomInput(String alg, int N, int T){ Random ra = new Random(); //使用算法alg将T个长度为N的数组排序 long total= 0 ; Long[] a = new Long[N]; for(int t=0;t<T;t++){ for(int i=0;i<N;i++) a[i]=ra.nextLong(); total+=time(alg, a); } return total; } public static void main(String[] args) { // TODO Auto-generated method stub String alg1=args[0]; String alg2=args[1]; int N=Integer.parseInt(args[2]); int T=Integer.parseInt(args[3]); long t1=timeRandomInput(alg1,N,T); long t2=timeRandomInput(alg2,N,T); System.out.printf("For %d random Longs\n %s is ", N, alg1); System.out.printf("%.1f times faster than %s\n ", (float)t2/t1, alg2); }}
阅读全文
0 0
- 1.Java实现各种排序
- Java实现各种排序
- Java实现各种排序
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法Java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- 各种排序算法java实现
- java中的各种排序实现
- 各种排序算法java实现
- const变量赋值原则
- Java学习6:this(隐式参数)关键字内存分析详解及用法
- AE调用 AddField 对 COM 组件的调用返回了错误 HRESULT E_FAIL。-2147467259
- 单链表环入口另类找法,很好理解
- Intro to Bilinear Maps
- 1.Java实现各种排序
- 文档就绪事件--document.ready和onload的区别
- Linux网络编程基础(二)
- C++函数的返回值(中)
- 过路费,白书P331UVa10537(dijkstra算法逆推应用,最短路径保存)
- Java 入门
- Maven 的pom.xml文件结构之基本配置parent和继承结构
- 技术人员的发展之路
- day6 类和集合