1.插入排序
/*插入排序
最好复杂度:O(n)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性 :稳定
补充 :STL的sort算法和stdlib的qsort算法中,
都将插入排序作为快速排序的补充,用于少量元素的排序,通常为8个一下。
*/
public class InsertionSort {
public static void insertionSort(int[] array,int first,int last)
{
int temp;
for (int i=first+1;i<=last;i++)
{
temp=array[i];
int j=i-1;
while((j>=first) && array[j]>temp)
{
array[j+1]=array[j];
j--;
}
array[j+1]=temp;
}
}
}
2.希尔排序
/*希尔排序
最好复杂度:O(n)
最坏复杂度:O(nlogn)
平均复杂度:..
空间复杂度:O(1)
稳定性 :稳定
补充 :就是直接插入排序的dx大小分类。
*/
public class ShellSort {
public static void shellSort(int[] arrays,int first,int end)
{
int temp;
int gap=0;//跳跃间隔
int length=end-first+1;
int j=0;
while(gap<=length)
{
gap=gap*3+1;
}
while(gap>0)
{
for(int i=first+gap;i<=end;i++)
{
j=i-gap;
temp=arrays[i];
while((j>=0) && (arrays[j]>temp))
{
arrays[j+gap]=arrays[j];
j=j-gap;
}
arrays[j+gap]=temp;
}
gap=(gap-1)/3;
}
}
}
3.二分查找插入排序
/*二分插入排序
最好复杂度:O(nlogn)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性 :稳定
补充 :当n比较大时,总排序码的比较次数比直接插入排序的最差情况好得多,但比最好情况要差。
*/
public class BinaruInsertSort {
public static void binaryInsertSort(int[] arrays,int first,int last)
{
int temp,left,right,middle;
for (int i=first+1;i<=last;i++)
{
temp=arrays[i];
left=first;
right=i-1;
while(left<=right)
{
middle=(left+right)/2;
if (arrays[middle]>temp) right=middle-1;
else left =middle+1;
}
for (int j=i-1;j>=left;j--) arrays[j+1]=arrays[j];
arrays[left]=temp;
}
}
}
4.冒泡排序
/*冒泡排序
最好复杂度:O(n)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性 :稳定
补充 :冒泡排序最坏的情况下,需要进行O(n^2)次交换,而插入排序只要最多O(n)的交换。
比插入排序差很多
在第一次内部循环实行时,使用旗标来表示是否需要交换的可能,也有可能那最好的时间复杂度到O(n)
对于比较的效果减少。
下面的程序已经加了标志位mark;
*/
public class BubbleSort {
public static void bubbleSort(int[] arrays,int first,int last)
{
int i=last;
int temp;
boolean mark=true;
while(i>first && mark)
{
mark=false;
for (int j=first;j<=i-1;j++)
if (arrays[j]>arrays[j+1])
{
temp=arrays[j];
arrays[j]=arrays[j+1];
arrays[j+1]=temp;
mark=true;
}
i--;
}
}
}
5.鸡尾酒排序
/*鸡尾酒排序/双向冒泡排序
最好复杂度:O(n)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性 :稳定
补充 :其实就是双向的冒泡排序,同样
*/
public class CocktailSort {
public static void cocktailSort(int[] arrays,int first,int end)
{
int temp;
while(first<end)
{
for (int j=end;j>first;j--)
if (arrays[j]<arrays[j-1])
{
temp=arrays[j];
arrays[j]=arrays[j-1];
arrays[j-1]=temp;
}
first++;
for (int j=first;j<end;j++)
if (arrays[j]>arrays[j+1])
{
temp=arrays[j];
arrays[j]=arrays[j+1];
arrays[j+1]=temp;
}
end--;
}
}
}
6.选择排序
/*选择排序
最好复杂度:O(n^2)
最坏复杂度:O(n^2)
平均复杂度:O(n^2)
空间复杂度:O(1)
稳定性 :不稳定
补充 :最好情况,已经有序,交换0次,最坏情况,交换n-1次,
比较次数n(n-1)/2;判断比交换速度快,所以选择排序比冒泡排序快
*/
public class SelectionSort {
public static void selectionSort(int[] arrays,int first,int last)
{
int min;
int temp;
for (int i=first;i<=last-1;i++)
{
min=i;
for (int j=i+1;j<=last;j++)
if (arrays[min]>arrays[j]) min=i;
if (min!=i)
{
temp=arrays[min];
arrays[min]=arrays[i];
arrays[i]=temp;
}
}
}
}
7.快速排序
/*快速排序
最好复杂度:O(nlogn)
最坏复杂度:O(n^2)
平均复杂度:O(nlogn)
空间复杂度:O(log2n)
稳定性 :不稳定
补充 :虽然是nlogn但是理论上最快
本程序选用第一个作为基准,如果需要别的数如随机数做基准只需要
pivot与arrays[first]交换
Partiton切割函数
*/
public class QuickSort {
public static void quickSort(int[] arrays,int first,int end)
{
int i,j;
int pivot=arrays[first];
if(first<end)
{
i=first;
j=end;
do
{
while (arrays[j]>pivot && i<j)
j--;
if (i<j)
{
arrays[i]=arrays[j];
i++;
}
while (arrays[i]<pivot && i<j)
i++;
if(i<j)
{
arrays[j]=arrays[i];
j--;
}
} while(i!=j);
arrays[i]=pivot;
quickSort(arrays,first,i-1);
quickSort(arrays,i+1,end);
}
}
}
8.分治排序
/*分治排序
最好复杂度:O(nlogn)
最坏复杂度:O(nlogn)
平均复杂度:O(nlogn)
空间复杂度:O(n)
稳定性 :稳定
补充 :内存上需要线性,对于大量数据一次性内存读不完的数据不行。
*/
public class SortingOrder {
private static void mergeArrays(int[] arrays,int first,int mid,int end)
{
int i=first;
int j=mid+1;
int k=0;
int[] temp=new int[end-first+1];
while(i<=mid && j<=end)
{
if (arrays[i]<=arrays[j]) temp[k++]=arrays[i++];
else temp[k++]=arrays[j++];
}
while (i<=mid) temp[k++]=arrays[i++];
while (j<=end) temp[k++]=arrays[j++];
System.arraycopy(arrays,first, temp,0, end-first+1);
}
public static void mergeSort(int[] arrays,int first,int end)
{
if (first<end)
{
int mid=(first+end)/2;
mergeSort(arrays,first,mid);
mergeSort(arrays,mid+1,end);
mergeArrays(arrays,first,mid,end);
}
}
}
9.堆排序
/*堆排序
最好复杂度:O(nlogn)
最坏复杂度:O(nlogn)
平均复杂度:O(nlogn)
空间复杂度:O(1)
稳定性 :不稳定
补充 :做一次堆调整的时间复杂度为O(logn)
用来维护一个K大的数列的最好选择
JAVA中PriorityQueue的底层实现。
floor() 向下取整
大顶堆维护
*/
public class HeapSort {
private static int getParent(int i)
{
return (int) Math.floor((i-1)/2);
}
private static int getLeftChildren(int i)
{
return 2*i+1;
}
private static int getRightChildren(int i)
{
return 2*i+2;
}
private static void heapAdjust(int[] arrays,int i,int size)
{
int l=getLeftChildren(i);
int r=getRightChildren(i);
int largest;
int temp;
if(l<size && arrays[l]>arrays[i]) largest=l;
else largest=i;
if(r<size && arrays[r]>arrays[largest]) largest=r;
if (largest!=i)
{
temp=arrays[i];
arrays[i]=arrays[largest];
arrays[largest]=temp;
}
heapAdjust(arrays,largest,size);
}
private static void buildHeap(int[] arrays,int size)
{
for (int i=size/2;i>=0;i--) heapAdjust(arrays,i,size);
}
public static void heapSort(int[] arrays,int size)
{
buildHeap(arrays,size);
int temp;
for(int i=size-1;i>=0;i--)
{
temp=arrays[0];
arrays[0]=arrays[i];
arrays[i]=temp;
heapAdjust(arrays,0,i);
}
}
}
10.桶排序
/*桶排序
最好复杂度:O(n)
最坏复杂度:O(n)
平均复杂度:O(n)
空间复杂度:O(n)
稳定性 :稳定
补充 :桶内使用插入排序,那么桶排序的平均时间复杂度为线性
最快
但是非常耗空间
对于数据密集型非常好用且不大的情况
*/
public class BucketSort {
public static void bucketSort(int[] arrays,int max)
{
int[] bucket=new int[max+1];
for (int i=0;i<arrays.length;i++)
bucket[arrays[i]]=arrays[i];
int i=0;
int j=0;
while(i<arrays.length && j<=max)
{
if(bucket[j]!=0) arrays[i++]=bucket[j];
j++;
}
}
}
11.计数排序
/*计数排序
最好复杂度:O(n+k) n个数从 0-k的范围 类似于桶排序
最坏复杂度:O(n+k)
平均复杂度:O(n+k)
空间复杂度:O(n)
稳定性 :稳定
补充 :只能对整数进行排序,
其次需要数据量小。
*/
public class CountingSort {
public static void countingSort(int[] arrays,int max)
{
int[] counting=new int[max+1];
for (int i=0;i<arrays.length;i++) counting[arrays[i]]++;
int k=0;
for (int i=0;i<=max;i++)
while (counting[i]!=0) arrays[k++]=i;
}
}
12.基数排序
/*基数排序
最好复杂度:O(n*k) n是排序元素个数,k是数字位数。
最坏复杂度:O(n*k)
平均复杂度:O(n*k)
空间复杂度:O(n+r) r是桶个数
稳定性 :稳定
补充 :按照从小到大的位数以此比较
*/
public class CardinalitySort {
public static void cardinalitySort(int[] arrays,int k)
{
int length=arrays.length;
int i=0;
int index=1;
int[][] temp =new int[10][length];//桶链
int[] order=new int[10];//桶长
while(i<=(k-1))
{
for(int j=0;j<length;j++)
{
int lsd=(arrays[j]/index)%10;
temp[lsd][order[lsd]++]=arrays[j];
}
int in=0;
for (int j=0;j<10;j++)
{
if (order[j]!=0)
{
for (int d=0;d<order[j];d++)
arrays[in++]=temp[j][d];
}
}
i++;
index*=10;
}
}
}
总结: