排序算法,插入、快速、希尔、基数、归并排序的代码实现和效率分析
2014-09-30 15:31
531 查看
排序算法,插入、快速、希尔、基数、归并排序
效率分析
代码实现
效率分析
代码实现
package puretest; import java.util.ArrayList; import java.util.List; public class paixu { /** * 归并排序,稳定的排序。 * 将序列分为2个子序列,对子序列排序(迭代) * 再将已经排序好的子序列合并 * 最差时间复杂度(nlog n),最优时间复杂度(n) * 平均时间复杂度(nlog n)最差空间复杂度(n) * @param nums * @param low * @param high * @return */ public Comparable[] mergesort(Comparable[] nums, int low, int high) { int mid = (low + high) / 2; if (low < high) { // 左边 mergesort(nums, low, mid); // 右边 mergesort(nums, mid + 1, high); // 左右归并 merge(nums, low, mid, high); } return nums; } public void merge(Comparable[] nums, int low, int mid, int high) { Comparable[] temp = new Comparable[high - low + 1]; int i = low;// 左指针 int j = mid + 1;// 右指针 int k = 0; // 把较小的数先移到新数组中 while (i <= mid && j <= high) { if (nums[i].compareTo( nums[j])>0) { temp[k++] = nums[i++]; } else { temp[k++] = nums[j++]; } } // 把左边剩余的数移入数组 while (i <= mid) { temp[k++] = nums[i++]; } // 把右边边剩余的数移入数组 while (j <= high) { temp[k++] = nums[j++]; } // 把新数组中的数覆盖nums数组 for (int k2 = 0; k2 < temp.length; k2++) { nums[k2 + low] = temp[k2]; } } /** * 快速排序,将序列按某个值分为两个子序列,第一个序列都小于该值,第二个序列则大于该值 * 然后再对子序列进行迭代。 * 最差时间复杂度(n^2),最优(nlogn),平均(nlogn) * @param data * @param min * @param max */ public void QuickSort(Comparable []data,int min ,int max){ if(min<max){ int mid = getmid(data,min,max); QuickSort(data,min,mid-1); QuickSort(data,mid+1,max); } } private int getmid(Comparable[] data, int min, int max) { <span style="white-space:pre"> </span> /** <span style="white-space:pre"> </span> * <p>Title: getmid</p> <span style="white-space:pre"> </span> * <p>Description: </p> <span style="white-space:pre"> </span> */ Comparable temp=data[min]; while(min<max) { <span style="white-space:pre"> </span> if(min<max&&data[max].compareTo(temp)>0) <span style="white-space:pre"> </span> max--; <span style="white-space:pre"> </span> data[min]=data[max]; <span style="white-space:pre"> </span> if(min<max&&data[max].compareTo(temp)<0) <span style="white-space:pre"> </span> min++; <span style="white-space:pre"> </span> data[max]=data[min]; } data[min]=temp; return min; } /** * 插入排序 * 构建有序序列,对于未排序数据, * 在已排序序列中从后向前扫描,找到相应位置并插入。 * 最差时间复杂度 O(n^2),最优时间复杂度 O(n),平均时间复杂度O(n^2) * @param data */ public void insertionSort(Comparable []data){ //插入排序 1 for(int index=1;index<data.length;index++){ Comparable key = data[index]; int position = index; //shift larger values to the right while(position>0&&data[position-1].compareTo(key)>0){ data[position] = data[position-1]; position--; } data[position]=key; } } /** * 插入排序 * @param c1 * @return */ public Comparable[] insertSort(Comparable[] c1) { //插入排序2 for(int i=1; i<c1.length; i++) { for(int j=i; j>0; j--) { if(c1[j].compareTo(c1[j-1])>0) { Comparable temp = c1[j]; c1[j] = c1[j-1]; c1[j-1] = temp; } else { break; } } } return c1; } /** * 希尔排序,对插入排序的变形,非稳定排序算法, * 根据步长d来讲序列分为d个子序列,再对子序列排序 * 然后再将d缩小,再次排序... * 已知的最好步长串行是由Sedgewick提出的 (1, 5, 19, 41, 109,...),本文采用1+3*n * @param c3 */ public void ShellSort(Comparable[] c3) { <span style="white-space:pre"> </span> /** <span style="white-space:pre"> </span> * <p>Title: ShellSort</p> <span style="white-space:pre"> </span> * <p>Description: </p> <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span> int d = 1; <span style="white-space:pre"> </span> while(d<c3.length/3) <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> d=d*3+1; <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> //d=d/3; <span style="white-space:pre"> </span> for(;d>=1;d=d/3) <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> for(int k=0;k<d;k++) <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> for(int i = d+k;i<c3.length;i=i+d) <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> for (int j = i; j >= d && c3[j].compareTo(c3[j-d]) < 0; j-=d) { <span style="white-space:pre"> </span> Comparable temp = c3[j]; <span style="white-space:pre"> </span> c3[j]=c3[j-d]; <span style="white-space:pre"> </span> c3[j-d]=temp; <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> } /** * 基数排序,将数值按照位数进行排序,依次对最高位,次高位...排序,最差时间复杂度O(kN),k为最大值位数 * @param a */ public void radixSort(int[] a){ <span style="white-space:pre"> </span> radixsort(a); } public static void radixsort(int[] array){ //首先确定排序的趟数; int max=array[0]; for(int i=1;i<array.length;i++){ if(array[i]>max){ max=array[i]; } } int time=0; //判断位数; while(max>0){ max/=10; time++; } //建立10个队列; List<ArrayList> queue=new ArrayList<ArrayList>(); for(int i=0;i<10;i++){ ArrayList<Integer> queue1=new ArrayList<Integer>(); queue.add(queue1); } //进行time次分配和收集; for(int i=0;i<time;i++){ //分配数组元素; for(int j=0;j<array.length;j++){ //得到数字的第time+1位数; int x=array[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i); ArrayList<Integer> queue2=queue.get(x); queue2.add(array[j]); queue.set(x, queue2); } int count=0;//元素计数器; //收集队列元素; for(int k=0;k<10;k++){ while(queue.get(k).size()>0){ ArrayList<Integer> queue3=queue.get(k); array[count]=queue3.get(0); queue3.remove(0); count++; } } } } public static void datemin(int longs,int max) { <span style="white-space:pre"> </span> paixu pai = new paixu(); <span style="white-space:pre"> </span> Comparable []c1=new Comparable[longs]; Comparable []c2=new Comparable[longs]; Comparable []c3=new Comparable[longs]; Comparable []c4=new Comparable[longs]; int[] a = new int[longs]; for(int i = 0;i<c1.length;i++) { Comparable key =Math.random()*max; c1[i]=key; c2[i]=key; c3[i]=key; c4[i]=key; a[i]= (int) (Math.random()*max); } long Mili0=System.currentTimeMillis();// 当前时间对应的毫秒数 System.out.println("基数排序"); //radixSort(a); long Mili1=System.currentTimeMillis();// 当前时间对应的毫秒数 System.out.println("结束 s"+(Mili1-Mili0)); System.out.println("归并排序"); pai.mergesort(c1,0,c1.length-1); long Mili2=System.currentTimeMillis(); System.out.println("结束 s"+(Mili2-Mili1)); System.out.println("快速排序"); pai.QuickSort(c2,0,c2.length-1); long Mili3=System.currentTimeMillis(); System.out.println("结束 s"+(Mili3-Mili2)); System.out.println("希尔排序"); pai.ShellSort(c3); long Mili4=System.currentTimeMillis(); System.out.println("结束 s"+(Mili4-Mili3)); } public static void main(String []args){ int longs=1000000; int max=10000; datemin( longs, max); } }
相关文章推荐
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序的C++代码实现
- Java-十种内部排序实现(选择,冒泡,插入,希尔,堆,归并,快速,基数,计数,桶)及代码下载
- 常见内部排序算法 简单数组实现与分析(快速(偶原创partition函数,望众高手指正)、归并、希尔、插入、选择、冒泡)
- 选择,插入,希尔,快速,堆,归并排序六种排序方式的Java 实现和性能对比(付代码)
- 希尔(shell)排序算法分析与代码实现
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 小白学数据结构——四、排序算法Python(冒泡、选择、快速、插入、希尔、归并排序)
- 排序算法的C++实现与性能分析(插入排序、归并排序、快速排序、STOOGE排序、堆排序)
- 排序算法Python(冒泡、选择、快速、插入、希尔、归并排序)
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- 10种排序算法总结(冒泡、选择、插入、希尔、归并、快速、堆、拓扑、锦标赛、基数)
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- Java语言实现九大排序算法(快速、归并、堆、选择、插入、计数、基数、希尔、冒泡)
- PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】
- 001-简单的java代码实现几种排序算法(插入,快速,冒泡,选择)
- 10种排序算法总结(冒泡、选择、插入、希尔、归并、快速、堆、拓扑、锦标赛、基数)
- 《冒泡,选择,插入,归并,希尔,快速》排序算法java实现一览
- Golang代码搜集-常用排序算法冒泡、选择、插入、希尔、快速
- 排序算法Python(冒泡、选择、快速、插入、希尔、归并排序)
- 七大排序算法(冒泡,选择,插入,二分法排序,希尔,快速,合并,堆排序)的java实现