package wzy.java.Base;
public class sort {
public static void main(String[] args) {
int[] data = {2, 5, 3, 1, 7, 4, 9, 0};
// maoPaoSort(data);
// quickSort(data);
incorporateSort(data);
System.out.println(java.util.Arrays.toString(data));
}
// 插入排序
/* 平均时间复杂度:O(N^2)
最差时间复杂度:O(N^2)
空间复杂度:O(1)
排序方式:In-place
稳定性:稳定*/
void insertSort(int arr[], int len){
// 检查数据合法性
if(arr == null || len <= 0){
return;
}
for(int i = 1; i < len; i++){
int tmp = arr[i];
int j;
for(j = i-1; j >= 0; j--){
//如果比tmp大把值往后移动一位
if(arr[j] > tmp){
arr[j+1] = arr[j];
}
else{
break;
}
}
arr[j+1] = tmp;
}
}
public static void maoPaoSort(int[] data){
/*1)按照从小到大的最终顺序来看。先比较相邻元素,如果第一个比第二个大,则交换。
2)按照每对相邻元素重复以上步骤,知道结尾最后一对,最后数即为最大数。
3)重复以上步骤,除了最后一个数
4)持续每次对越来越来的元素重复以上步骤,直到没有比较
时间复杂度为 n^2 空间复杂度为 o1 稳定排序算法
*/
// 检查数据合法性
if (data == null || data.length <= 0)
System.out.println("开始排序");
int arrayLength = data.length;
for (int i = 0; i < arrayLength-1; i++) {
for (int j = 0; j < arrayLength-1-i; j++) {
if (data[j] > data[j+1]){
int tmp = data[j+1] ;
data[j+1] = data[j];
data[j] = tmp;
}
}
}
System.out.println(java.util.Arrays.toString(data));
}
public static void quickSort (int[] data){
/*
1)定基准。随意挑选一个元素为基准值(一般取第一个)。
2)重新排序。将小于基准值的元素放在左边,大于基准值的元素放在右边。此次完成后,基准值换成中间位置。
3)递归的把小于基准值的子序列和大于基准值的子序列排序。
时间复杂度 O(nlog2n) 空间复杂度 O(log2n)
*/
quickSortMain(data, 0, data.length-1);
}
public static void quickSortMain(int[] data, int left, int right) {
int i, k, key;
i = left;
k = right;
key = data[i];
if (i >= k)
return;
if(i < k){
while (i < k){
// 从右往左找比节点小的数,循环结束要么找到了,要么i=j
while (data[k] >= key && i < k){
k--;
}
// 从左往右找比节点大的数,循环结束要么找到了,要么i=j
while (data[i] <= key && i < k) {
i++;
}
if (i < k) {
int tmp = data[i];
data[i] = data[k];
data[k] = tmp;
}
}
data[left] = data[i];
data[i] = key;
quickSortMain(data, left, i-1);
quickSortMain(data, i+1, right);
System.out.println(java.util.Arrays.toString(data));
}
}
public static void incorporateSort (int[] data){
// 归并排序,是创建在归并操作上的一种有效的排序算法。算法是采用分治法(Divide and Conquer)的一个非常典型的应用,
// 且各层分治递归可以同时进行。归并排序思路简单,速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
/*
归并排序是用分治思想,分治模式在每一层递归上有三个步骤:
分解(Divide):将n个元素分成个含n/2个元素的子序列。
解决(Conquer):用合并排序法对两个子序列递归的排序。
合并(Combine):合并两个已排序的子序列已得到排序结果。
平均时间复杂度:O(nlogn)
最佳时间复杂度:O(n)
最差时间复杂度:O(nlogn)
空间复杂度:O(n)
排序方式:In-place
稳定性:稳定
*/
int []temp = new int[data.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
sort(data,0,data.length-1,temp);
}
private static void sort(int[] arr,int left,int right,int []temp){
if(left<right){
int mid = (left+right)/2;
sort(arr,left,mid,temp);//左边归并排序,使得左子序列有序
sort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序
merge(arr,left,mid,right,temp);//将两个有序子数组合并操作
}
}
private static void merge(int[] arr,int left,int mid,int right,int[] temp){
int i = left;//左序列指针
int j = mid+1;//右序列指针
int t = 0;//临时数组指针
while (i<=mid && j<=right){
if(arr[i]<=arr[j]){
temp[t++] = arr[i++];
}else {
temp[t++] = arr[j++];
}
}
while(i<=mid){//将左边剩余元素填充进temp中
temp[t++] = arr[i++];
}
while(j<=right){//将右序列剩余元素填充进temp中
temp[t++] = arr[j++];
}
t = 0;
//将temp中的元素全部拷贝到原数组中
while(left <= right){
arr[left++] = temp[t++];
}
}
}