基础排序
冒泡排序
时间复杂度O(n2) 空间复杂度O(1) 稳定
public void bubbleSort(int[] a){
for(int i = 0; i <a.length; i++) {
for(int j = 0; j < a.length-i-1; j++) {
if(a[j] > a[j+1]) {
int temp = a[j + 1];
a[j+1] = a[j];
a[j] = temp;
}
}
}
}
选择排序
时间复杂度 O(n2) 空间复杂度O(1) 不稳定
public void selectSort(int[] a){
for(int i = 0; i <a.length; i++) {
int min = i;
for(int j = i+1; j < a.length; j++) {
if(a[j] < a[min]) {
min = j;
}
}
int temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
插入排序
时间复杂度 O(n2) 空间复杂度O(1) 稳定
public void insertSort(int[] a){
for(int i = 1; i <a.length; i++) {
int j;
int temp = a[i];
for(j = i; j>0 && temp<a[j-1]; j--) {
a[j] = a[j-1];
}
a[j] = temp;
}
}
希尔排序
思路:希尔排序的中心思想是将数据进行分组,然后对每一组数据进行插入排序,在每一组数据都有序后,再对所有的分组利用插入排序进行最后一次排序。
希尔排序时间复杂度平均为O(nlogn),最好与最坏情况要根据具体的增量序列来判断,最坏为O(n2),空间复杂度O(1),不稳定。
public void shellSort(int[] a){
int gap = 0;
for(gap = a.length/2;gap>0;gap/=2){
for(int i=gap;i<a.length;i++){
int j;
int temp = a[i];
for(j=i;j>=gap&&(temp<a[j-gap]);j-=gap)
a[j] = a[j-gap];
a[j] = temp;
}
}
}
快速排序
平均复杂度为O(nlogn),最坏时间复杂度 O(n2) 空间复杂度O(logn),由于递归造成,不稳定。
public void quickSort(int[] a,int left,int right){
if(left>right) return;
int i = left;
int j = right;
int t = a[left];
while(i!=j){
while(a[j]>=a[left] && i<j)
j--;
while(a[i]<=a[left] && i<j)
i++;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
a[left] = a[i];
a[i] = t;
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
归并排序
归并排序的运行时间最差、最好和平均都是O(nlogn),空间复杂度为O(n)。因为没有数据交换,所以是稳定的。
public static void mergeSort(int[] a){
int[] temp = new int[a.length];
remergeSort(a,0,a.length-1,temp);
}
public static void remergeSort(int[] a,int left,int right,int[] temp){
if(left<right){
int mid = (left+right)/2;
remergeSort(a,left,mid,temp);
remergeSort(a,mid+1,right,temp);
mergeArray(a,left,mid,right,temp);
}
}
public static void mergeArray(int[] a,int left,int mid,int right,int[] temp){
int k=0;
int i = left,m=mid;
int j = mid+1,n=right;
while(i<=mid && j<=right){
if(a[i]<=a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while(i<=m){
temp[k++] = a[i++];
}
while(j<=n){
temp[k++] = a[j++];
}
for(i=0;i<k;i++){
a[left+i] = temp[i];
}
}
堆排序
时间复杂度 O(nlogn) 空间复杂度O(1) 不稳定
public static void heapSort(int[] a){
//从第一个非叶子节点从下往上开始调整
for(int i=a.length/2-1;i>=0;i--){
heapAdjust(a,i,a.length);
}
for (int i = a.length - 1; i > 0; i--) {
// 最后一个元素和第一元素进行交换
int temp = a[i];
a[i] = a[0];
a[0] = temp;
// 筛选 R[0] 结点,得到i-1个结点的堆
//此处的i=length-1,初始化时传入的是length(容易写为length-1)
heapAdjust(a,0,i);
}
}
public static void heapAdjust(int[] a,int i,int length){
int temp = a[i];
int child = 2*i+1;
while(child<length){
if(child+1<length && a[child]<a[child+1])
child++;
if(temp>=a[child])
break;
a[i] = a[child];
i = child;
child = 2*child +1;
}
a[i] = temp;
}