排序算法整理(Java)
1. 直接插入排序(Insert Sort)
1.1 思路:
1.将待排序序列分为有序区和无序区,初始时,有序区为待排序记录第一个,无序区为剩下所有。
2.将无序区的第一个记录插入到有序区合适位置中,无序区记录减一,有序区加一。
3.重复步骤2,到无序区没有记录为止。
算法适用于少量数据的排序,时间复杂度为O(n^2),是稳定的排序方法。
1.2 算法实现
/**
* 插入排序算法
* 1.将数组分为有序区和无序区,初始有序区为数组第一个记录,无序区为剩下的记录。
* 2.将无序区第一个记录插入到有序区的合适位置,有序区增加一个记录,无序区减少一个记录
* 3.重复步骤二,直至无序区无记录。
* @param array
*/
public static void InsertSort(int [] array){
for (int i = 1; i < array.length; i++) {//第一次比较
int temp = array[i]; //记录下a[1]的值 a[1] = 64 ,无序区第一位
int j = i; // j=1
while ( j>0 && temp < array[j-1]){ //比较 有序区第一位 无序区第一位 即a[1] < a[0]时,数据前移一位 j>0 防止数据下标溢出
array[j] = array[j-1]; //a[1] = a[0]
j--; // j=0
}
array[j] = temp; //把a[1] 的值存储到 a[0] 交换完成
} //之后第二次 i=2 比较部分执行两次 因为有序区有两个元素,如此类推,最后完成排序
//printArray(array);
}
2.希尔排序(Shell Sort)
2.1 思路:
基本上和插入排序相同
区别:每次循环的步长,通过减半的方式来实现
说明:基本原理和插入排序类似,不一样的地方在于。通过间隔多个数据来进行插入排序。
算法适用于少量数据的排序,时间复杂度为取决于n,是不稳定的排序方法。
2.2算法实现
/**
* 基本上和插入排序相同
* 区别:每次循环的步长,通过减半的方式来实现
* 说明:基本原理和插入排序类似,不一样的地方在于。通过间隔多个数据来进行插入排序。
* 算法适用于少量数据的排序,时间复杂度为取决于n,是不稳定的排序方法。
* @param arry
*/
public static void ShellSort(int [] arry){
for (int i = arry.length / 2; i > 0; i /= 2) {
//i层循环控制步长
for (int j = i; j < arry.length; j++) {
//j控制无序端的起始位置
for (int k = j; k > 0 && k - i >= 0; k -= i) {
if (arry[k] < arry[k - i]) {
int temp = arry[k - i];
arry[k - i] = arry[k];
arry[k] = temp;
} else {
break;
}
}
}
//j,k为插入排序,不过步长为i
}
printArray(arry);
}
3.冒泡排序(Bubble Sort)
3.1 思路:
1.第一位开始,相邻两位比较,若后一位小于前一位就交换位置,否则不变。
2.每循环一个size长度次数,最后一位一定为最大。
3.即所需循环次数每次-1。
时间复杂度为O(n^2),是稳定的排序方法。
3.2算法实现
/**
* 冒泡排序
* 相邻两位比较,若后一位小于前一位就交换位置,否则不变。
* 每循环一个size长度次数,最后一位一定为最大
* @param array
*/
public static void BubbleSort(int [] array){
for (int i = 0; i < array.length-1; i++) { //第一次循环 i=0时,比较n次,最后一位保证为最大值
for (int j =0; j<array.length-1-i;j++) { //第二次循环 i=1时,最后一位确定为最大值,只需要比较n-1次
if (array[j] > array[j + 1]) { // a[0] 和 a[1] 比较,大于则交换位置,小于则不变
int temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
//printArray(array);
}
4.快速排序(Quick Sort)–是冒泡排序的改进版
4.1 思路:
基本思想:首先选择一个轴值(provit),将待比较序列分成独立的两个部分。
左侧记录的关键码都小于或等于轴值,右侧都大于或等于轴值。
然后分别对这两个子序列重复上述过程。
时间复杂度为O(n(log2)n),是不稳定稳定的排序方法。
4.2 算法实现
3.1 首先进行一次划分算法,将待排序序列分为两个部分。
/**
* 一次排序算法
* @param array
* @param begin
* @param end
* @return
*/
public static int Partition(int [] array, int begin,int end) {
int i=begin;
int j=end;
while (i<j){ //第一次排序 i=0 j=6
//对右侧扫描
while (i<j && array[i] <= array [j]){ //if i<j a[i]<=a[j]成立 则j坐标前移一位
j--;
}
int temp = array[i]; //if a[i]<=a[j]不成立 则交换两坐标值
array[i] = array[j];
array[j] = temp;
if (i<j){ //且i坐标后移一位
i++;
}
//同理对右侧扫描
while (i<j && array[i] <= array[j]){
i++;
}
if (i<j){
int temp1 = array[i];
array[i] = array[j];
array[j] = temp1;
j--;
}
}
return i; //返回轴点
}
2.快速排序算法
/**
* 快速排序
* @param array
*/
public static void QuickSort(int [] array){
int begin = 0;
int end = array.length-1;
if (begin<end){
int pivote = Partition(array,0,6); //调用 进行第一次排序,得到轴点且根据轴点分为左右两侧两个子序列
Partition(array,begin,pivote-1); //对左侧子序列进行排序
Partition(array,pivote+1,end); //对右侧子序列进行排序
}
printArray(array);
}