1.希尔排序
又叫sell排序,任何情况下时间复杂度均为O(n^(3/2))即 O(n^1.3~1.5), 只需要一个额外的空间,所以空间复杂度是最佳的。不稳定
选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,
冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
希尔排序思想:原理有点像直接插入法,但它可以减少数据搬移次数,排序的原则是将数据分成特定间隔的小组,以直接插入法排完小组内的数据后再减少间隔的距离重新分组,再排序,再分再排,最后以所有数据为一个大组,再用直接插入法比较,因为直接插入法就是越有序越快,所以分组每组排序后就让每组数据变得有序,提高了算法的效率,所以sell排序也叫直接插入法的优化。
package javapaixu;
import java.util.Arrays;
public class Xier {
public static void sell(int[] array,int gap) {//gap分组
int tmp = 0;
int j = 0;
for(int i = gap;i < array.length;i++) {
tmp = array[i];
for(j = i-gap;j >= 0;j -= gap) {
if(array[j] > tmp) {
array[j+gap] = array[j];
}else {
break;
}
}
array[j+gap] = tmp;
}
}
public static void sellSort(int[] array){
int[] d = {3,1};//分组
for(int i=0;i<d.length;i++){
sell(array,d[i]);//调用比较方法,也就是变态了的直接插入排序法
}
}
public static void main(String[] args) {
int[] array={101,213,12,98,45,36};
sellSort(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
[12, 36, 45, 98, 101, 213]
1.快速排序
快速排序就是分割交换的排序方法,是目前公认的最佳排序方法,在最快以及平均情况下,时间复杂度为O(nlogn)。最坏情况就是每次挑中的基准值不是最大就是最小,其时间复杂度为O(n^2);它有跳跃式交换,不稳定,在最差情况下的空间复杂度为O(n),而最佳情况下为O(nlogn)。快速排序法是平均运行时间最快的排序法。
快速排序的思想:它的原理和冒泡排序一样,都是用交换的方式,不过它会现在数据中找一个基准,把小于这个基准的数据放在左边,大于基准的放在右边。再以同样的方式处理两边的数据。
现定义两个下标,low和high分别指向第一个和最后一个,low从前往后走,high从后往前走,一般第一次以第一个元素为基准:
把小于这个基准的数据放在左边,大于基准的放在右边:
代码如下:
int tmp = array[low];
while(low < high) {
while(low < high && array[high] >= tmp) {
--high;
}
array[low] = array[high];
while(low < high && array[low] <= array[high]) {
++low;
}
array[high] = array[low];
}
实例:
因为进不去第一个while循环语句,所以直接把array[high]的值给array[low].
while(low < high && array[high] >= tmp) {
--high;
}
array[low] = array[high];
然后进入第二个while循环:
while(low < high && array[low] <= array[high]) {
++low;
}
array[high] = array[low];
不满足第二个while循环,跳出,把array[low]的值给array[high]:
又开始外面的大while循环,这次条件满足,可以进入第一个while循环:
现在不满足第一个while循环的条件,跳出,把array[high]的值给array[low]:
再次进入第二个while循环:
条件不满足,跳出,把array[low]的值给array[high]:
再一次开始外面的大while循环 :
进入第一个while循环:
因为low=high,跳出外面的大while循环:
外面的大while循环完成,跳出,比较完一趟,确定了选的基准的有序位置,然后在再这个有序元素进行两边同样的比较,直至所有的元素位置都确定了就排序完了。
递归法
package javapaixu;
import java.util.Arrays;
/**
* 快速排序,递归实现
* 时间复杂度:好:O(无序)(nlog2n),坏(有序):O(n^2)
* 空间复杂度:
* 稳定性:不稳定
* @author 李正全
*/
public class Kuaisu {
public static int partion(int[] array,int low,int high) {//一趟快排
int tmp = array[low];
while(low < high) {
while(low < high && array[high] >= tmp) {
--high;
}
array[low] = array[high];
while(low < high && array[low] <= array[high]) {
++low;
}
array[high] = array[low];
}
array[low] = tmp;
return low;
}
public static void Quick(int[] array,int start,int end) {
int par = partion(array,start,end);
if(par > start+1) {//左边
Quick(array,start,par-1);
}
if(par < end-1) {//右边
Quick(array,par+1,end);
}
}
public static void QuickSort(int[] array) {
Quick(array,0,array.length-1);
}
public static void main(String[] args) {
int[] array = {20,1,9,56,25,32,87,45,12,69,54,19};
QuickSort(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
[1, 9, 12, 19, 20, 25, 32, 45, 54, 56, 69, 87]
非递归法
就是用队列的方式去实现:
package javapaixu;
import java.util.Arrays;
/**
* 快速排序,非递归实现
* 时间复杂度:好:O(无序)(nlog2n),坏(有序):O(n^2)
* 空间复杂度:
* 稳定性:不稳定
* @author 李正全
*/
public class Kuaisu1 {
public static int partion(int[] array,int low,int high) {//一趟快排
int tmp = array[low];
while(low < high) {
while(low < high && array[high] >= tmp) {
--high;
}
if(low >= high) {
break;
}else {
array[low] = array[high];
}
while(low < high && array[low] <= array[high]) {
++low;
}
if(low >= high) {
break;
}else {
array[high] = array[low];
}
}
array[low] = tmp;
return low;
}
public static void QuickSort(int[] array) {
int[] stack = new int[array.length];
int top = 0;
int low = 0;
int high = array.length-1;
int par = partion(array,low,high);
//入栈
if(par > low+1) {
stack[top++] = low;
stack[top++] = par-1;
}
if(par < high-1) {
stack[top++] = par+1;
stack[top++] = high;
}
//出栈
while(top > 0) {
high = stack[--top];
low = stack[--top];
par = partion(array,low,high);
if(par > low+1) {
stack[top++] = low;
stack[top++] = par-1;
}
if(par < high-1) {
stack[top++] = par+1;
stack[top++] = high;
}
}
}
public static void main(String[] args) {
int[] array = {1,9,56,25,32,7,87,45,12,20,69,3,54,19};
QuickSort(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
[1, 3, 7, 9, 12, 19, 20, 25, 32, 45, 54, 56, 69, 87]