Java排序之选择排序、插入排序、希尔排序
来源:互联网 发布:淘宝卡价格刷单权重 编辑:程序博客网 时间:2024/05/19 18:00
排序算法
package Suanfa;public class Suanfa1 {public static void sort(Comparable[] a) {}public static boolean less(Comparable v, Comparable w) {return v.compareTo(w)<0;//判断v是否小于w}public static void exch(Comparable[] a,int i,int j) {Comparable t=a[i];//将数组位置i和位置j元素交换a[i]=a[j];a[j]=t;}public static void show (Comparable[] a) {for (int i=0;i<a.length;i++) System.out.print(a[i]+" ");System.out.println();}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) {String[] a= {"A","F","C","E","D"};sort(a);assert isSorted(a);show(a);}}
选择排序
首先找到数组中最小的元素,将它和数组中的第一个元素交换。再次,在剩下的元素中找到最小的,和第二个元素交换。如此往复,直到所有元素都有序。
不断的在剩下数组中找最小的,然后和未排序的第一个交换。
public static void SelectSort(Comparable[] a) {//按升序排序int len=a.length;for (int i=0;i<len;i++) {int min=i;//定义初始化的最小数索引,不断的在内循环中更新最小数索引for (int j=i;j<len;j++) {if (less(a[j],a[min])) min=j;}exch(a,i,min);//在外循环,交换最小索引和当前索引}}
选择排序的内循环就是找出当前元素(包含)后面的所有元素中的最小元素。然后在外循环中交换当前元素和最小元素。
因此交换的总次数为len。
对于长度为N的数组,选择排序需要N^2/2次比较和N次交换。
总共有N次交换,总共需要比较(N-1)+(N-2)+(N-3)+(N-4)+.....+2+1=N(N-1)/2~N^2/2
特点:
运行时间和输入无关,每一次找出剩余数组的最小元素并能为下次排序提供任何信息。一个已排序的数组和随机数组排序时间相同。
数据移动是最少的,每次都只交换两个数组元素,总共只交换N次。
时间复杂度为O(n^2),空间复杂度为O(1)。
冒泡排序
相邻的元素两两比较,顺序相反则交换,每次都将最大的元素排到最后。若是倒序,则每次交换比较的次数是N+N-1+N-2+...+1=N(N-1)/2,时间复杂度为O(n2)
public static void BubbleSort(Comparable[] a) {int N=a.length;for(int i=0;i<N-1;i++) {for(int j=0;j<N-i-1;j++) {if(less(a[j+1],a[j])) {exch(a,j,j+1);}}}}第一要遍历所有元素将最大元素移到(不断的交换)最右端,之后遍历前面还未排序的元素,将次大的元素移到倒数第二位置。
插入排序
插入排序是将未排序的数组(右侧),插入到已排序的数组(左侧),从后向前扫描,插入到左侧已排序的数组中,使得左侧始终保持有序。
插入排序所需要的时间取决有输入元素的初始顺序。
1.从第一个元素开始,该元素可以认为已经有序。
2.取出下一个元素,在已经排序的数组中,从后向前扫描。
3.如果该元素(已排序)大于新元素(未排序),则将两元素交换。
4.当所有比新元素大的所有元素都交换完后,该新元素就插入到已排序数组中。
public static void InserSort(Comparable[] a) {int len=a.length;for (int i=1;i<len;i++) {for (int j=i;j>0&&less(a[j],a[j-1]);j--) {exch(a,j,j-1);}}}
对于随机排序的长度为N且主键不重复的数组,平均情况下,插入排序需要~N^2/4次比较以及N^2/4次交换。最坏情况下需要N^2/2次比较和N^2/2次交换。最好情况下需要N-1次比较和0次交换。
倒置:是指数组中两个顺序颠倒的两个元素。
插入排序需要交换操作和数组中倒置的数量相同,需要比较次数大于等于倒置的数量,小于等于倒置的数量加上数组大小再减一。
要大幅度提高插入排序的速度,需要在内循环中,将较大元素向右移动而不是总是不断的交换两个元素。(这样访问数组的次数能减半)。
对于随机排序的无重复主键的数组,插入排序和选择排序的运行时间都是平凡级别的,两者之间的比是一个较小的常数。
插入排序平均时间复杂度O(n^2),最好O(n),平均O(n^2),辅助空间O(1)
希尔排序
希尔排序是一种基于插入排序的快速排序算法。
希尔排序是使得数组中任意间隔为h的元素都是有序的。这样的数组称为h有序数组。
希尔排序一次能够移动h位,而插入排序一次只能移动1位。
将h按照N/3逐渐递减。
public static void ShellSort(Comparable[] a) {int len=a.length;int h=1;while(h<len/3) h=3*h+1;//得到最大的h,再逐渐h/3,直到h=1while(h>=1) {for(int i=h;i<len;i++) {//将i从h到len,虽然最开始只是两个h有序数组比较,但之后会有更多的h有序数组比较for(int j=i;j>=h&&less(a[j],a[j-h]);j-=h) {exch(a,j,j-h);//每次都将a[j]和a[j-h],a[j-2*h]...元素交换,即每次移动可以移动h位}}h=h/3;}}
希尔排序又称为递减增量排序,这里选择的递增序列为h=3*h+1。
如何选取递增序列也是重要问题。
希尔排序是一种不稳定排序算法,排序时间为
平均O(nlogn)~O(n^2),最好情况为O(n^1.3),最坏情况为O(n^2).辅助空间O(1)
- Java排序之选择排序、插入排序、希尔排序
- 希尔排序,选择排序,插入排序 java
- Java基础篇之----排序(快速排序、冒泡排序、堆排序、简单选择排序、 希尔排序、直接插入排序)
- 冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序java实现
- 选择排序、插入排序、希尔排序
- 选择排序&插入排序&希尔排序
- 选择排序,插入排序,希尔排序
- 选择排序、插入排序、希尔排序总结
- Java实现插入排序之希尔排序
- Java实现选择排序、插入排序、希尔排序算法
- 【排序】冒泡排序、选择排序、插入排序、希尔排序
- 插入排序之希尔排序
- 插入排序之希尔排序
- 插入排序之希尔排序
- 插入排序之希尔排序
- 插入排序之希尔排序
- 插入排序之希尔排序
- 插入排序之希尔排序
- JS HTTP 请求终极解决方案
- BZOJ 1179 ATM (强连通分量缩点+spfa最长路)
- 对接短信平台实现短信提醒
- HMM与CRF
- Java类中加载Spring配置文件步骤
- Java排序之选择排序、插入排序、希尔排序
- 浅谈i++与++i的区别&传参时的操作
- MyBatis批量删除
- CodeForces
- CSS3新增长度单位
- python用函数声明类
- 机器学习的训练算法(优化方法)汇总——梯度下降法及其改进算法
- 图像配准小结
- 绘制误差条形图