package sort;
import java.util.Arrays;
public class SortTest {
public static void main(String[] args)
{
int[] arrTemp = {1,23,5,45,25,34,15,37,46,6,849,4,57,31,86,74,32,374,498,876,221,334,81,49,39,231,8,2,321,3,51};
new SortTest().quickSort(arrTemp,0,arrTemp.length-1);
//new SortTest().shellSort(arrTemp,arrTemp.length);
//new SortTest().mergeSort(arrTemp,1,arrTemp.length);
for(int itemp : arrTemp)
{
System.out.println(itemp);
}
}
/** 排序总结
* 不需要开辟空间的排序 插入/快速/堆
* 稳定排序 插入/归并
* 时间复杂度 插入O(N*N) 归并/快速/堆 O(N*logN)
* 空间复杂度 插入/堆 O(1) 归并排序 O(N) 快排O(logN)
*/
//快速排序 也是二分法排序 原理根据最后一个节点二分 然后递归快速排序方法
void quickSort(int array[],int iStart,int iEnd)
{
int iCenter = sortAndReturn(array,iStart,iEnd);
if(iCenter-1>iStart) quickSort(array,iStart,iCenter-1);
if(iCenter+1<iEnd)quickSort(array,iCenter+1,iEnd);
}
int sortAndReturn(int array[],int iStart,int iEnd)
{
//如果基本有序数组的话 这种方法会接近N平方的时间复杂度 可以考虑增加一个random方法
//取得iStart 和 iEnd之间的一个random值 exchange(array,random,iEnd);
int i=iStart-1;
for (int j=iStart;j<iEnd;j++)
{
if(array[j]<=array[iEnd])
{
i++;
if(i!=j)
exchange(array,i,j);
}
}
exchange(array,++i,iEnd);
return i;
}
void exchange(int array[],int iLeft,int iRight)
{
int temp=array[iLeft];
array[iLeft]=array[iRight];
array[iRight]=temp;
}
//归并排序 也称合并排序 原理是分解->排序->合并 使用递归方式调用 注意 分解时候要根据长度 不能根据index值
void mergeSort(int array[],int iStart,int iEnd)
{
if(iStart>=iEnd) return;
int iCenter= (iEnd+iStart)/2;
mergeSort(array,iStart,iCenter);
mergeSort(array,iCenter+1,iEnd);
merge(array,iStart,iCenter,iEnd);
}
void merge(int array[],int iStart,int iCenter,int iEnd)
{
int iAllLength=iEnd-iStart;
if(iAllLength<1) return;
int[] arrLeft = Arrays.copyOfRange(array,iStart-1,iCenter);
int[] arrRight = Arrays.copyOfRange(array,iCenter,iEnd);
int i1=0,i2=0;
for (int i=iStart-1;i<=iEnd-1;i++)
{
if(i1>=arrLeft.length)
{
if(i2>=arrRight.length) break;
array[i]=arrRight[i2];
i2++;
}
else if(i2>=arrRight.length)
{
if(i1>=arrLeft.length)break;
array[i]=arrLeft[i1];
i1++;
}
else if(arrLeft[i1]>arrRight[i2])
{
array[i]=arrRight[i2];
i2++;
}
else
{
array[i]=arrLeft[i1];
i1++;
}
}
}
//希尔排序 不稳定 其实就是分组插入排序, 也称为缩小增量排序. 比普通的插入排序拥有更高的性能.
void shellSort(int array[],int count)
{
for (int dk = count / 2; dk > 0; dk = dk / 2) {
// dk增量
for (int i = 0; i < dk; i++) {
// 直接插入排序
for (int j = i + dk; j < count; j += dk) {
if (array[j] < array[j - dk]) {
// 如果相邻的两个元素, 后者比前者大, 则不用调整
int temp = array[j];
int k = j - dk;
while (k >= 0 && array[k] > temp) {
// 每次while循环结束后, 保证把最小的插入到每组的最前面
array[k + dk] = array[k];
k -= dk;
}
// 每组第一个元素为最小的元素
array[k + dk] = temp;
}
}
}
}
}
//插入排序 稳定 从无序区域中找第一个元素插入有序区域固定位置,有序区域初始默认长度为1
void insertSort(int array[],int count)
{
int iTemp=0;
for(int i=1;i<count-1;i++)
{
for(int j=0;j<i;j++)
{
if(array[i+1]<array[j])
{
iTemp=array[j];
array[j]=array[i+1];
array[i+1]=iTemp;
break;
}
}
}
}
//选择排序 不稳定 每次从无序区中找出最小的元素, 跟无序区的第一个元素交换
void SelectSort(int array[],int count)
{
int iTemp=0;
for(int i=0;i<count;i++)
{
int iMin = i;
for(int j=i+1;j<count;j++)
{
if(array[iMin]>array[j])
{
iMin=j;
}
}
iTemp=array[i];
array[i]=array[iMin];
array[iMin]=iTemp;
}
}
//冒泡排序 稳定 原理 : 每次对比相邻两项的元素的大小, 不符合顺序则交换
void MPSort(int array[],int count)
{
int iTemp=0;
for(int i=0;i<count;i++)
{
for(int j=i+1;j<count;j++)
{
if(array[i]>array[j])
{
iTemp=array[i];
array[i]=array[j];
array[j]=iTemp;
}
}
}
}
void HeapSort(int array[],int count)
{
//不使用堆的堆排序 不实现了
}
}