插入排序
基本思想:从数组的第二个元素开始,若比前一个元素小,就向前移动(若大于就不用移动),直到插入到合适的位置,然后再去排第三个元素,依次类推,最后一个插入到合适位置时,数组的排序就完成了。
流程如图所示:
代码如下:
/**
* 直接插入排序
* @date 2018-10-18
* @param arr
*/
public static void sort1(int arr[]){
int temp;
int j;
for(int i = 1;i<arr.length;i++){
temp = arr[i];
for(j = i;j > 0 && temp <arr[j-1];j--){
arr[j] = arr[j-1]; //前一个较大的元素换到 j 下标位置
}
arr[j] = temp; //上述条件不满足时的 j 下标位置就是temp适合的位置,temp保存元素插入到此
}
System.out.println(Arrays.toString(arr));
}
希尔排序
针对插入排序的下效率问题,有人对次进行了改进与升级,这就是现在的希尔排序。希尔排序,称也。递减增量排序算法,是插入排序的一种更高效的改进版本希。尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
- 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
- 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位
流程是:设置一个整数k = length / 2,将下标相差为k的元素组成一个数列,并将其排序
如果k> 1,就重复上面的操作,当k = 1时,对此时的数组插入进行排序
流程如图产品:
代码如下:
public static void sheelSort(int [] a){
int len=a.length;//单独把数组长度拿出来,提高效率
while(len!=0){
len=len/2;
for(int i=0;i<len;i++){//分组
for(int j=i+len;j<a.length;j+=len){//元素从第二个开始
int k=j-len;//k为有序序列最后一位的位数
int temp=a[j];//要插入的元素
while(k>=0&&temp<a[k]){//从后往前遍历
a[k+len]=a[k];
k-=len;//向后移动len位
}
a[k+len]=temp;
}
}
}
System.out.println(Arrays.toString(a));
}
选择排序
每次从待排序的数据元素中选择最大或最小的一个元素,放在待排序数列的最前面
流程如图:
代码入下:
/**
* 选择排序
* @date 2018-10-18
* @param arr
*/
public static void sort3(int arr[]){
int len=arr.length;
for(int i=0;i<len;i++){//循环次数
int min=arr[i];
int position=i;
for(int j=i+1;j<len;j++){//找到最小的值和位置
if(arr[j]<min){
min=arr[j];
position=j;
}
}
arr[position]=arr[i];//进行交换
arr[i]=min;
}
}
冒泡排序
基本思想:从第一个元素开始,与下一个元素比较,若大于则交换位置,小于则不动,所以会经过N-1趟排序,每一趟会把大的元素沉底,小的元素浮上来,所以叫冒泡排序。
流程如图所示:代码如下:
/**
* 冒泡排序
* @date 2018-10-18
* @param arr
*/
public static void sort2(int arr[]){
int temp;
int j;
for(int i = 0;i<arr.length-1;i++){ //n个数要循环n-1趟
for(j = 0;j < arr.length-i-1;j++){
if(arr[j] > arr[j + 1]){ //比后一个元素大,就交换两数位置
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
快速排序
前面几种排序不管是从理解和代码的层面都比较简单,面试中文到排序你要能手撸快速排序,并讲解出来的话排序基本就没有问题。这几种排序快排速度是最快的。
基本思想:。通过一轮的排序将序列分割成独立的两部分,其中一部分序列的值均比另一部分的值小继续对长度较短的序列进行同样的分割,最后到达整体有序在排序过程中,由于已经分开的两部分的元素不需要进行比较,故减少了比较次数,降低了排序时间。
详细描述:选择序列的第一个元素ARR [0]为基准值,先从后往前比较(基准值选择的是ARR [0],就从后往前,原因和简单,考虑下前后相遇的情况),用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的索引和从后往前比较的索引相等,将这个索引上的值和基准值对调,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。然后再将左右两边的序列递归调用改方法,直至排序完成。
流程图如下:
代码如下:
/**
* @param arr
* @param start 一般传入0
* @param end 一般传入arr[arr.length-1]
*/
public static void quickSort(int arr[] ,int start,int end) {
if(start > end){
return;
}
int i = start;
int j = end;
int baseNum = arr[i];
//循环将数字分为左右两边
while(i != j){
while(arr[j] >= baseNum && j>i){
j--;
}
while(arr[i] <= baseNum && j>i){
i++;
}
//将满足条件的值交换位置
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//两边相遇后将相遇的位置的值和基准值调换位置
arr[start] = arr[i];
arr[i] = baseNum;
//分左右两种情况递归
quickSort2(arr,start,i-1);
quickSort2(arr,j+1,end);
}
如有问题,欢迎指正!