一、O(n^2)排序算法
(一)、冒泡排序
package Sort_Zhu;
public class MpSort {
public static void main(String[] args) {
int[] a = new int[]{3,52,15,62,9,32};
mpsort(a,6);
for (int i = 0; i < a.length;i++){
System.out.println(a[i]);
}
}
public static void mpsort(int[] a, int n){
if (n == 1){
return;
}
for (int i = 0; i < n; i++){
boolean flag = false;
for (int j = 0;j < n -i - 1; j++){
if (a[j] > a[j+1]){
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
flag = true;
}
}
if (!flag){
break;
}
}
}
}
(二)、插入排序
package Sort_Zhu;
public class InsertSort {
public static void main(String[] args) {
int[] a = new int[]{6,52,3,12,35,91};
insertsort(a,6);
for (int i = 0; i < a.length;i++){
System.out.println(a[i]);
}
}
public static void insertsort(int[] a,int n){
if (n == 1){
return;
}
for (int i = 1; i < n; i++){
int tmp = a[i];
int j = i - 1;
for (;j >= 0; j--){
if (a[j] > tmp){
a[j+1] = a[j];
}else{
break;
}
}
a[j+1] = tmp;
}
}
}
(三)、选择排序
package Sort_Zhu;
public class SelectSort {
public static void main(String[] args) {
int[] a = new int[]{3,52,6,16,4,9};
selectsort(a,6);
for (int i = 0; i < a.length; i++){
System.out.println(a[i]);
}
}
public static void selectsort(int[] a,int n){
if (n == 1){
return;
}
for (int i = 0; i < n; i++){
int min = a[i];
int k = i;
for (int j = i + 1;j < n; j++){
if (a[j] < min){
min = a[j];
k = j;
}
}
int tmp = a[i];
a[i] = min;
a[k] = tmp;
}
}
}
二、O(nlogn)排序算法
(一)、合并排序
package Sort_Zhu;
public class MergeSort {
public static void mergesort(int[] a,int left,int right,int[] tmp){
if (left < right){
int mid = (left + right) / 2;
mergesort(a,left,mid,tmp);
mergesort(a,mid+1,right,tmp);
sort(a,left,mid,right,tmp);
}
}
public static void sort(int[] a,int left,int mid,int right,int[] tmp){
int i = left;
int j = mid + 1;
int index = 0;
while (i <= mid && j <= right){
if (a[i] > a[j]){
tmp[index] = a[j];
index++;
j++;
}else{
tmp[index] = a[i];
index++;
i++;
}
}
while(i <= mid){
tmp[index] = a[i];
index++;
i++;
}
while(j <= right){
tmp[index] = a[j];
index++;
j++;
}
index = 0;
while (left <= right){
a[left] =tmp[index];
left++;
index++;
}
}
public static void main(String[] args) {
int[] a = new int[]{38,12,5,98,42,7,342,11,52,62,98,13,41,512,53,111};
int[] tmp = new int[a.length];
mergesort(a,0,a.length - 1,tmp);
for (int i = 0; i < a.length;i++){
System.out.println(a[i]);
}
}
}
(二)、快速排序
package Sort_Zhu;
public class QuickSort {
public static void quicksort(int[] a,int p,int q){
if (p >= q){
return;
}
int r = partition(a,p,q);
quicksort(a,p,r-1);
quicksort(a,r+1,q);
}
public static int partition(int[] a,int start,int end){
int provt = a[end];
int i = start;
for (int j = start;j < end;j++){
if (a[j] < provt){
swap(a,i,j);
i += 1;
}
}
swap(a,end,i);
return i;
}
public static void swap(int[] a,int i,int j){
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
public static void main(String[] args) {
int[] a = new int[]{342,62,12,52,6,9,23,85,92,215};
quicksort(a,0,a.length - 1);
for (int i = 0; i < a.length;i++){
System.out.println(a[i]);
}
}
}
三、O(n)排序算法
(一)桶排序(Bucket Sort)
- 将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序,桶内排完序之后,再把每个桶里的数据按照顺序取出则为有序的数据
- 桶排序的时间复杂度为O(n),假设有n个数据,m个桶,每个桶内都有n/m = k个数据,每个桶都使用快排,时间复杂度为O(klogk),m个桶就为O(m * k * log k) => O(n * log(n /m)),当m的个数无限趋近于n时,log(n/m)就是个非常小的常量,桶排序的时间复杂度就趋近于O(n)
- 桶排序要求还是比较苛刻的,首先桶与桶之间要有天然的大小顺序,这样桶内的数据排序完之后,不需要再对桶与桶之间排序;其二,各个桶内的数据分布要均匀,若数据全到一个桶内,时间复杂度又退化为O(nlogn)
- 桶排序比较适合用在外部排序中,即内存有限,可以把数据分在各个桶内,使桶内的数据能够放在内存中进行排序
(二)计数排序(Counting Sort)
- 桶排序的一种特殊情况,针对数据范围比数据个数小的情况,比如给50万高考考生成绩排序,高考成绩总分为750分,可以划分为751个桶,相同成绩的考生放在一个桶内,只需遍历扫描桶,即可完成排序操作
(三)基数排序(Radix Sort)
- 把待排序的数据转化为计数排序或桶排序
- 如有10万个手机号码,把这10个号码按照从小到大排序,因为手机号码为11位,数据范围是远大于数据个数10万个的,所以不适合用桶排或计数排,这里有一种巧妙的思路,把11位手机号码先按照倒数第一位排序,然后按照倒数第二位排序,依次类推,11次排序即可,这11次排序可以使用桶排序或计数排序
- 注意基数排序必须依赖稳定排序算法,如排到后面有132××××和182××××两个号码,若不是稳定排序,排第一位的时候只会按第一位排序,不管之前排好的先后顺序,182很可能在132前面
四、如何选择一个合适的排序算法?