在本章节将介绍Java几种常见的排序算法,在这里将这些代码写出为了方便自己以后复习,同样希望能够对大家产生帮助。
接下来将按一下的顺序来讲解几种排序算法:
- 冒泡排序
- 插入排序
- 选择排序
- 快速排序
- 归并排序
冒泡排序:
在各种排序的算法中,冒泡排序是最简单的排序算法,方法比较简单就不多做介绍。冒泡排序的最坏时间复杂度为 O(n^2)
package Sort;
/**
* @author:MindMrWang
*2017年11月13日
*:function:冒泡排序
*/
public class BubbleSort {
public static void main(String[] args) {
int [] a= {1,3,55,34,99,99,88,102};
sort(a);
for(int i=0;i<a.length;i++) {
System.out.println(a[i]);
}
}
public static void sort(int []a) {
int tmp;
for(int i=1;i<a.length;i++) {
for(int j=0;j<(a.length-i);j++) {
if(a[j]>=a[j+1]) {
tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
}
}
优化:
设置一个flag=0,在第一个for循环里面,判断当if(a[j]>=a[j+1]) 时将flag置为1,若一次循环结束,flag还为0,那么break跳出循环,完成排序。节省了已经 排序好,还要进行比较的操作。
package Sort;
/**
* @author:MindMrWang
*2017年11月13日
*:function:优化冒泡排序
*/
public class DoubleSort {
public static void main(String[] args) {
int [] a= {1,3,55,34,99,99,88,102};
sort(a);
for(int i=0;i<a.length;i++) {
System.out.println(a[i]);
}
}
public static void sort(int []a) {
int tmp;
for(int i=1;i<a.length;i++) {
int flag=0;
for(int j=0;j<(a.length-i);j++) {
if(a[j]>=a[j+1]) {
flag=1;
tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
if(flag==0)
break;
}
}
}
冒泡排序优化二
用一个变量记录下最后一个发生交换的位置,后面没有发生交换的已经有序 所以可以用这个值来作为下一次比较结束的位置。
这个和上面的思想相同,但是实现上面反而有些复杂,不推荐使用。
插入排序:
插入排序分为几种:
①简单插入排序
②希尔排序
③折半插入排序
首先先说一下简单插入排序:
图片来自百度百科
首先想一下什么事插入排序?插入排序就是将一个数(key)向已经排好顺序的一组数字里面插入。和已经排序好的一组数进行比较,若key小于比较的数,那么将key插入刚和它比较的数的前面。
首先一个数字第一个数一定是有序的。
第一次只需要从数组的第二个数key=a[1]开始插入,若a[1]小于前面的a[0],那么将a[0]后移一位。比较结束后就能确定将要插入的值具体插入的位置。
第二次将第三个数key=a[2]和前面的a[1]比较,若key小于前面的a[1],那么将a[1]后移一位。然后将继续和a[0]比较,若key小于a[0],那么将a[0]后移一位。比较结束后就能确定将要插入的值具体插入的位置。
下面以此类推。
知道比较n-1次结束
package Sort;
public class insertSort {
public static void main(String[] args) {
int []a= {12,434,66,2,4,99,55};
sort(a);
for(int c:a) {
System.out.println(c);
}
}
public static void sort(int[]a) {
for(int i=1;i<a.length;i++) {
int key=a[i];//要插入的值
int j=i-1;//要插入的值要和前面的i-1个数进行比较
for(;j>=0&&a[j]>key;j--) {
a[j+1]=a[j];
}
//当j--后,发现不能循环后,所以要插入的位置为最后一次和a[j]比较的位置
a[j+1]=key;//因为当满足条件(j>=0&&a[j]>a[i])的时候j--,所以确切的位置j+1是我们想要插入的位置。
}
}
}
以上的的代码只是实现插入排序的一种方式,还有其他的实现方式;下面这段代码是从百度百科copy来的,仅供大家参考:
/**
*插入排序
*@paramarr
*@return
*/
private static int[] insertSort(int[]arr){
if(arr == null || arr.length < 2){
return arr;
}
for(inti=1;i<arr.length;i++){
for(intj=i;j>0;j--){
if(arr[j]<arr[j-1]){
//TODO:
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}else{
//接下来是无用功
break;
}
}
}
return arr;
}
个人感觉两种方法第二种实现的比较好,第二种算法还对数组进行了判断,但是怎么感觉这种算法都像是一种交换类算法,而不是插入算法。
但是确实也用的插入思想,只是实现上面用了交换手段(比第一种算法在循环语句上多进行了两次赋值,从效率的角度上看,第二种没有第一种执行效率高)。