一、快速排序
//快速排序
public static void quickSort(int[] arr, int low , int high){
if(low < high){
int low1 = low;
int high1 = high;
int temp = arr[low]; 设立基准值
while(low1 < high1){
//从后向前找小于temp的数
// 当队尾的元素大于等于基准数据时,向前挪动high指针;
while(low1 < high1 && arr[high1] >= temp) high1--;
//如果队尾元素小于temp了,就跳出循环。数值交换,需要将其赋值给low
if(low1 < high1) arr[low1] = arr[high1];
//从前向后找小于temp的数
// 当队首元素大于temp时,需要将其赋值给high
while(low1 < high1 && arr[low1] < temp) low1 ++;
if(low1 < high1) arr[high1] = arr[low1];
}
arr[low1] = temp;
quickSort(arr, low ,low1-1);//递归调用,处理半部分
quickSort(arr, low1+1 ,high);//递归调用,处理半部分
}
}
public static void main (String[] arr){
int[] array = {2,52,7,9,13,23,56,90,34,23,57,34};
quickSort(array,0,array.length-1);
for(int i : array){
System.out.print(i + " ");
}
//打印结果:2 7 9 13 23 23 34 34 52 56 57 90
}
快速排序的过程是定基准值,分而治之。时间复杂度为O(nlogn), 空间复杂度为O(logn)~O(n),不稳定类型的。
二、冒泡排序的一种写法
public static void bubbleSort(int[] arr){
int temp; //临时变量
for(int i = 0; i < arr.length - 1; i++){
for(int 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;
}
}
}
}
冒泡排序的时间复杂度为O(n^2), 空间复杂度O(1),稳定类型的。
三、堆排序
* 堆排序的基本思路:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
/* 堆排序的基本思路:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
*/
public class HeapSort {
public static void main (String[] arr){
int[] array = {2,52,7,9,13,23,56,90,34,23,57,34};
heapSort(array);
System.out.println(Arrays.toString(array));
//打印结果:[2, 7, 9, 13, 23, 23, 34, 34, 52, 56, 57, 90]
}
public static void heapSort(int[] arr){
for(int i = arr.length/2-1; i >= 0; i--){
buildMaxHeap(arr, i, arr.length);
}
for(int j = arr.length - 1; j > 0 ;j--){
swap(arr, 0, j);
buildMaxHeap(arr, 0, j);
}
}
/**
* 建立大顶堆
*/
public static void buildMaxHeap(int[] arr, int i, int length){
int temp = arr[i];//先取出当前元素i
for(int k= i*2+1; k<length; k=k*2+1){ //从i结点的左子结点开始,也就是2i+1处开始
if(k+1<length && arr[k] < arr[k+1]){//如果左子结点小于右子结点,k指向右子结点
k++;
}
if(arr[k] > temp){//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
arr[i] = arr[k];
i = k;
}else{
break;
}
}
arr[i] = temp;//将temp值放到最终的位置
}
/**
* 元素交换
* @param arr
* @param a
* @param b
*/
public static void swap(int[] arr, int a, int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
简单来讲:堆排序过程构建一个大顶堆或小顶堆,最大元素沉到数组末端,新的序列重新堆排序递归。
时间复杂度为O(nlogn),空间复杂度为O(1),不稳定类型
四、直接插入排序
//从第二个数开始比较插入,依次跟前一个数比较插入。
public static void straightSort(int[] arr,int len){
int tmp;
int i;
int j;
for (i = 1;i < len;i++)
{
tmp = arr[i];
for (j = i - 1;j >= 0 && arr[j] > tmp;j--)
{
arr[j + 1] = arr[j];
}
arr[j + 1] = tmp;
}
}
直接插入排序 时间复杂度为O(n^2),空间复杂度为O(1)
五、各类排序算法及时空复杂度,稳定性