1、堆排序(升序采用大顶堆)--时间复杂度:O(NlogN);不稳定;空间复杂度:O(1)
调整堆:从不满足堆的性质的节点开始(O(logN))
//调整堆;arr:待维护的数组,n:数组长度;i:待维护节点的下标
void heapify(int arr[],int n,int i){
int longest=i;
int lson=i*2+1;
int rson=i*2+2;
//找到节点值最大的下标
if(lson<n && arr[lson]>arr[longest])longest=lson;
if(rson<n && arr[rson]>arr[longest])longest=rson;
if(longest!=i){
int temp=arr[i];
arr[i]=arr[longest];
arr[longest]=temp;
heapify(arr,n,longest);//继续调整该节点对应的堆
}
}
建堆:(O(N))从有子节点的第一个节点开始
void heap_sort(int arr[],int n){
//建堆
for(int i=(n-1)/2;i>=0;i--){
heapify(arr,n,i);
}
//排序
for(i = n-1; i>0; i--){
//将堆顶元素和最后一个元素交换
int temp=arr[i];
arr[i]=arr[0];
arr[0]=temp;
//调整堆为大顶推 ,i表示排前i个元素
heapify(arr,i,0);
}
}
2 快速排序
对于基本有序表,为最坏情况,时间复杂度是O(n2),空间复杂度O(1)
分治,选择一个基准元素(base),通常选择第一个或最后一个元素;
通过第一轮扫描,比base小的元素都在base左边,比base大的元素都在base右边,再有同样的方法递归排序这两部分,直到序列中所有数据均有序为止。
需要有base,left指针,right指针
时间复杂度:平均O(nlogn),最好O(nlogn),最坏O(n2); 空间复杂度:O(logn);
/*
left:数组左边界
right:数组右边界
采用分治的思想,先找到 每次分割的点 pos ,再排序。
*/
public void quickSort(int[] arr, int left, int right){
if(left < right){
int pos = partition(arr, left, right);
quickSort(arr, left, pos - 1);
quickSort(arr, pos + 1, right);
}
}
public int partition(int[] arr, int left, int right){
int base = arr[left];
while(left < right){
while(left < right && arr[right] >= base){
right--;
}
arr[left] = arr[right];
while(left < right && arr[left] <= base){
left++;
}
arr[right] = arr[left];
}
arr[left] = base;
return left;
}
}
3 归并排序
时间复杂度:最好O(nlogn),最坏O(nlogn),平均O(nlogn)
空间复杂度:O(n)
void mergesort(int arr[],int p,int q){
if(p < q){
int r=(q-p)/2;
mergesort(arr,p,r);
mergesort(arr,r+1,q);
merge(arr,p,q,r);
}
}
void merge(int arr[],int p,int q,int r){//r是中间的下标
int L1,L2;
L1=r-p+1;
L2=q-r;
int L[50],R[50];
for(int i=0;i<L1;i++){
L[i]=arr[p+i];
}
for(int i=0;i<L2;i++){
R[i]=arr[r+1+i];
}
L[L1]=INT_MAX;
R[L2]=INT_MAX;
int i=0,j=0;
for(int k=p;k<=q;k++){
if(L[i]<R[j]){
arr[k]=L[i];
i++;}
else{
arr[k]=R[j];
j++;}
}
}
4 冒泡排序
时间复杂度:最好情况O(n),最坏O(n2),平均O(n2)
空间复杂度:O(1)
稳定
5 选择排序
时间复杂度:最好,最坏,平均:O(n2)
空间复杂度:O(1)
不稳定
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕
6 直接插入排序
对于基本有序的表,时间复杂度是O(n),空间复杂度是O(1)
时间复杂度:最好O(n),最坏O(n2),平均O(n2)
空间复杂度:O(1)
稳定
7希尔排序
递减增量排序算法
时间复杂度:平均O(nlogn),最好O(nlogn2),最坏O(nlogn2)
空间复杂度:O(1)
不稳定