简单的排序--冒泡、选择、插入、希尔、快排

1、冒泡排序时间复杂度O(n^2)
冒泡排序算法,比较相邻的两个数,否者比前者大,则交换。整个过程从开始的第一对到最后的一对。这步完成后最后的元素会是最大的,在对剩下的数进行比较交换,直到没有一对数字需要比较。
public class BubbleSort { public static void bubblesort(long[] arr){ long tmp = 0; for (int i = 0; i < arr.length -1 ; i++) { for (int j = arr.length -1;j>i;j--){ if (arr[j] < arr[j-1]){ tmp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = tmp; } } } } }
public static long[] sort(long[] arr){
for (int i = 1; i < arr.length;i++) {//冒泡次数n-1
for (int j = 0;j < arr.length-1;j++){
if (arr[j] > arr[j + 1]){
long tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
return arr;
}
2、选择排序O(n^2)
选择第一个数据作为最小值,依次与后面的数进行比较,找到比之更小的数,最后交换。
public class SelectionSort { public static void sort(long[] arr){ int k = 0; long tmp = 0; for (int i = 0; i < arr.length -1 ; i++) {//n -1 次比较 k = i; for(int j = i;j < arr.length;j++){ if(arr[j] < arr[k]){ k = j; } } tmp = arr[i]; arr[i] = arr[k]; arr[k] = tmp; } } }
public static long[] sort2(long[] arr){
for (int i = 0; i < arr.length -1;i++) {//n-1轮比较
int min = i;//选择第一个数最小
for (int j = i + 1;j < arr.length;j++){
if (arr[min] > arr[j]){
min = j;
}
}
if (i != min){
long tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}
}
return arr;
}
3、插入排序 最有O(n) 最坏O(n^2)
插入排序类是斗地主时马牌,把一张牌插入到适合它的位置上。
public class InsertSort { public static void sort(long[] arr) { long tmp = 0; for(int i = 1; i < arr.length; i++) { tmp = arr[i]; int j = i; while(j > 0 && arr[j -1] >= tmp) { arr[j] = arr[j - 1]; j--; } arr[j] = tmp; } } }
4、希尔排序
主要先寻找最大间隔,然后两两比较交换,当间隔为1时,就相当于插入排序。
public static void sort(long[] arr){ //初始化间隔 int h = 1; //计算最大间隔,最大间隔不大于数组的长度 while (h < arr.length / 3){ h = h * 3 + 1; } System.out.println(h); while (h > 0){ //进行插入排序 long tmp = 0; for (int i = h;i < arr.length;i++){ tmp = arr[i]; int j = i; while (j > h -1 && arr[j-h] >= tmp){ arr[j] = arr[j - h]; j -= h; } arr[j] = tmp; } // 减小间隔 h = (h - 1)/3; } }
5、归并排序

//两路归并算法,两个排好序的子序列合并为一个子序列 public static void merge(int[] a, int left, int mid, int right){ int []tmp=new int[a.length];//辅助数组 int p1=left,p2=mid+1,k=left;//p1、p2是检测指针,k是存放指针 while(p1<=mid && p2<=right){ if(a[p1]<=a[p2]) tmp[k++]=a[p1++]; else tmp[k++]=a[p2++]; } while(p1<=mid) tmp[k++]=a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中 while(p2<=right) tmp[k++]=a[p2++];//同上 //复制回原素组 for (int i = left; i <=right; i++) a[i]=tmp[i]; } public static void mergeSort(int [] a,int start,int end){ if(start<end){//当子序列中只有一个元素时结束递归 int mid=(start+end)/2;//划分子序列 mergeSort(a, start, mid);//对左侧子序列进行递归排序 mergeSort(a, mid+1, end);//对右侧子序列进行递归排序 merge(a, start, mid, end);//合并 } }
6、快排
先假定一个关键字,找到插入点,在左右递归排序。
//划分数组 public static int partition(long arr[],int left,int right,long point){ int leftptr = left - 1; int rightptr = right; while (true){ //循环,将比关键字小的留在左端 while (leftptr < rightptr && arr[++leftptr] < point); //循环,将比关键字大的留在右端 while (rightptr > leftptr && arr[--rightptr] > point); if (leftptr >= rightptr){ break; }else { //将比关键字大的移动到右端,小的移动到左端 long tmp = arr[leftptr]; arr[leftptr] = arr[rightptr]; arr[rightptr] = tmp; } } //最后, long tmp = arr[leftptr]; arr[leftptr] = arr[right]; arr[right] = tmp; return leftptr; } public static void sort(long[] arr,int left,int right){ if (right - left <= 0){ return; }else { //设置关键字 long point = arr[right];//采用最右端作为关键字 //获取切入点,并进行排序 int partition = partition(arr,left,right,point); sort(arr,left, partition-1); sort(arr, partition+1,right); } }

浙公网安备 33010602011771号