1、快速排序
“分而治之”的思想:把大的划分为小的,小的再拆分为更小的。
原理:对于一组给定的记录,通过一趟排序后,将原序列分为两部分,其中前一部分的所有记录均比后一部分的所有记录小,然后再依次对前后两部分的记录进行快速排序,递归该过程,直到序列中的所有记录均有序为止。
不稳定
平均、最好时间复杂度: O(nlogn)
最坏时间复杂度:O(n^2)
空间复杂度:O(logn)
n大时较好
public static void sort(int array[],int low,int hight){
int i,j;
int index;
if(low>=hight){
return;
}
i=low;
j=hight;
index=array[i];
while(i<j){
while(i<j&&array[j]>=index)
j--;
if(i<j)
array[i++]=array[j];
while(i<j&&array[i]<index)
i++;
if(i<j)
array[j--]=array[i];
}
array[i]=index;
sort(array,low,i-1);
sort(array,i+1,hight);
}
public static void quickSort(int array[]){
sort(array,0,array.length-1);
}
2、冒泡排序
思想:一轮比较(将第一个记录与相邻的记录比较,满足条件则交换位置,进行一轮比较和换位后,n个记录最大的位于第n位)
然后对前(n-1)个记录进行第二轮比较
稳定
最好:o(n)
最坏:o(n^2)
平均:o(n^2)
空间复杂度:o(1)
n小时较好
public class BubbleSort(int[] arr){
int temp;
for(int i=0;i<arr.length-1;++i){
for(int j=arr.length-1;j>i;--j){
if(arr[j]<arr[j-1]){
temp=arr[j-1];
arr[j-1]=arr[j];
arr[j]=temp;
}
}
}
}
3、直接插入排序
思想:对于给定的一组记录,初始时假设第一个记录自成一个有序序列,其余记录为无序序列。接着从第二记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至最后一个记录插入到有序序列中为止。
稳定
最好:o(n)
平均:o(n^2)
最坏:o(n^2)
空间复杂度:o(1)
大部分已有序时较好
从小到大排序
public static void insertSort(int[] array){
if(array!=null){
for(int i=1;i<array.length;i++){
int temp=a[i],j=i;
if(a[j-1]>temp){
while(j>=1&&array[j-1]>temp){
a[j]= a[j-1];
j--;
}
}
a[j]=temp;
}
}
4、简单选择排序
原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录进行交换;接着对不包括第一个记录以外的其他记录进行比较,得到最小的记录与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。
最好:o(n^2)
平均:o(n^2)
最坏:o(n^2)
空间复杂度:o(1)
不稳定
n小时较好
从小到大排序
public static void selectSort(int[] array){
int i;
int j;
int temp=0;
int flag=0;
int l=array.length;
for(i=0;i<l;i++){
temp=array[i];
flag=i;
for(j=i+1;j<l;j++){
if(array[j]<temp){
temp=array[j];
flag=j;
}
}
if(flag!=i){
array[flag]=array[i];
array[i]=temp;
}
}
}
5、归并排序
归并排序就是利用递归和分治技术将数据序列划分成为越来越小的半子表,再对半子表进行排序,最后再利用递归方法将排好序的半子表合并成为越来越大的有序序列。归并排序中,“归”代表递归的意思,即递归将数组折半的分离为单个数组,例如数组:【2,6,1,0】,会先拆半,分为【2,6】和【1,0】两个子数组,然后再拆半将数组分离,分为【2】、【6】、【1】、【0】。“并”就是将分开的数据按照从小到大的顺序或者从大到小的顺序再放到一个数组中。
原理:对于给定的一组记录(假设共有n个记录),首先将两个相邻的长度为1的子序列进行归并,得到n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列。
归并的关键两步:第一步,划分半子表;第二步,合并半子表。
稳定
最好:o(nlogn)
平均:o(nlogn)
最坏:o(nlogn)
空间复杂度:o(n)
n比较大时好
//归并排序
public static void merge(int[] array,int p,int q,int r){
int i,j,k,n1,n2;
n1=q-p+1;
n2=r-q;
int[] L=new int[n1];
int[] R=new int[n2];
for(i=0,k=p;i<n1;i++,k++){
L[i]=array[k];
}
for(i=0,k=q+1;i<n2;i++,k++){
R[i]=array[k];
}
for(k=p,i=0,j=0;i<n1&&j<n2;k++){
if(L[i]>R[j]){
array[k]=L[i];
i++;
}else{
array[k]=R[j];
j++;
}
}
if(i<n1){
for(j=i;j<n1;j++,k++){
array[k]=L[j];
}
}
if(j<n2){
for(i=j;j<n2;i++,k++){
array[k]=R[i];
}
}
public static void mergeSort(int[] array,int p,int r){
if(p<r){
int q=(p+r)/2;
mergeSort(array,p,q);
mergeSort(array,q+1,r);
merge(array,p,q,r);
}
}
}
6、希尔排序
希尔排序也称为“缩小增量排序”。
原理:先将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插入排序,待整个待排序序列“基本有序后”,最后再对所有元素进行一次直接插入排序。
不稳定
最好:o(n)
平均:o(nlogn)
最坏:o(n^s)1<s<2———(s是所选分组)
空间复杂度:o(1)
//希尔排序
public static void shellSort(int[] array){
int len=array.length;
int i,j;
int h;
int temp;
for(h=len/2;h>0;h=h/2){
for(i=h;i<len;i++){
temp=array[i];
for(j=i-h;j>=0;j-=h){
if(temp<array[i]){
array[j+h]=array[j];
}else{
break;
}
}
array[j+h]=temp;
}
}
}
7、堆排序
堆是一种特殊的树形数据结构,其每一个节点都有一个值,通常提到的堆都是指一颗完全二叉树,根节点的值小于(或大于)两个子节点的值,同时,根节点的两个子树也分别是一个堆。
堆排序是一种树形选择排序,在排序的过程中,将R[1...n]看作一颗完全二叉树的顺序存储结构,利用完全二叉树中的父节点和子节点之间的内在关系来选择最小的元素。
堆一般分为大顶堆和小顶堆两种不同的类型。
堆排序原理:对于给定的n个记录,初始时把这些n个记录看作一颗顺序存储的二叉树,然后将其调整为大顶堆,然后将堆的最后一个元素与堆顶元素(即二叉树的根节点)进行交换后,堆得最后一个元素即为最大记录;接着将前(n-1)个元素(即不包括最大记录)重新调整为一个大顶堆,再将堆顶元素与当前堆得最后一个元素进行交换后得到次大的记录,重复该过程直到调整的堆中只剩一个元素为止,该元素即为最小记录。此时可得到一个有序的序列。
堆排序主要包括两过程:一是构建堆;二是交换堆顶元素与最后一个元素的位置。
不稳定
最好时间复杂度:O(nlogn)
最坏时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)
空间复杂度:O(1)
n大时较好
public class HeapSort{
//从大到小进行排序
public static void adjustMinHeap(int[] array,int pos,int length){
int temp;
int child;
for(temp = array[pos];2*pos+1<=length;pos=child){
child=2*pos+1;
if(child<length&&array[child]>array[child+1]){
child++;
}
if(array[child]<temp){
array[pos]=array[child];
}else{
break;
}
}
array[pos]=temp;
}
public static void myMinHeapSort(int[] array){
int i;
int len=array.length;
for(i=len/2-1;i>=0;i--)
adjustMinHeap(array,i,len-1);
for(i=len-1;i>=0;i--){
int temp=array[0];
array[0]=array[i];
array[i]=temp;
adjustMinHeap(array,0,i-1);
}
}
public static void main(String[] args) {
int i=0;
int[] array = {1,5,38,0,57,25,23};
int len=array.length;
myMinHeapSort(array);
for(i=0;i<len;i++) {
System.out.println(array[i]);
}
}
}