排序算法分为4种,如图
其中,比较直观的三种排序算法是:冒泡排序,基本选择排序,基本插入排序;而快速排序是对冒泡排序进行了改进,堆排序基于选择排序思想的算法,shell排序是基于插入排序的算法。
以下对各大排序算法的代码展示:
1、冒泡排序
private static void bubleSort(int[] arr){
boolean flag = false;
for(int i = 0;i < arr.length-1; i++){
for(int j = 0; j < arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
//有交换,用一个标识去标识他
flag = true;
//交换数据
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
//flag = false;
}
if(!flag){
break;
}
System.out.print("第"+(i+1)+"趟的结果:"+flag);
print(arr);
flag= false;
}
}
冒泡排序算法,平均速度为O(n^2),最坏情况下的速度为O(n^2);
2、基本选择排序
private static void selectedSort(int[] arr){
int minIndex; //对应最小值的小标
int temp; //临时变量
for(int i = 0; i < arr.length-1; i++){
minIndex = i;
for(int j = i+1; j<arr.length;j++){
if(arr[j] < arr[minIndex]){
//注意这里不是交换
minIndex = j;
}
}
if(minIndex != i){ //说明已经发生交换的条件
//做交换
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
System.out.print("第"+(i+1)+"趟的结果:");
print(arr);
}
}
基本选择排序,平均速度为O(n^2),最坏情况下的速度为O(n^2)
3、基本插入排序
private static void insertionSort(int[] arr){
int j;
int temp;
for(int i = 1; i < arr.length; i++){
temp = arr[i];
j = i-1;
while(j>=0&&temp<arr[j]){
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
System.out.print("第"+i+"趟的结果:");
print(arr);
}
}
基本插入排序算法,平均速度为O(n^2),最坏情况的速度为O(n^2)
4、快速排序(冒泡排序的改进)
private static void quickSort(int[] arr, int left, int right){
int base; //分解值
int temp; //交换时做临时值
int ltemp, rtemp; //临时左下标,临时右下标
ltemp = left;
rtemp = right;
base = arr[(left+right)/2]; //临界值取中间,注意临界值可以不这样去
while(ltemp < rtemp){ //总的循环条件,左临界下标不能超过右临界下标
while(arr[ltemp] < base){
++ltemp;
}
while(arr[rtemp] > base){
--rtemp;
}
//当前两个循环结束了,也就是左侧第一次遇到值不小于临界值,
//右侧第一次遇到值不大于临界值
if(ltemp <= rtemp){ // 这个时候做交换
temp = arr[ltemp];
arr[ltemp] = arr[rtemp];
arr[rtemp] = temp;
//昨晚交换后左临时下标+1,右临时下标-1
++ltemp;
--rtemp;
}
if(ltemp == rtemp){
ltemp++;
}
//递归调用
if(left<rtemp){
quickSort(arr, left, ltemp-1);
}
if(right > ltemp){
quickSort(arr, rtemp+1, right);
}
}
}
快速排序算法,平均速度为O(nlogn),最坏情况下为O(n^2)
(对比冒泡排序,O(n^2),O(n^2))
5、堆排序(基于选择排序算法)
//堆排序
/**
* 这个排序直接保存它的代码就可以了,但是要理解他的思路
*/
private static void heapSort(int arr[]){
int i,j;
int h,k; //i,j,k都用来做下标表示
int temp;
int n = arr.length;
//构造对的算法
for(i = n/2-1; i >= 0; i--){ //将a[0,n-1]构成大顶堆
while(2*i+1<n){ //第i个结点有右子树
j = 2*i+1;
if(j+1 < n){
if(arr[j] < arr[j+1]){
j++;
}
}
if(arr[i]<arr[j]){ //比较i与j为序号的数据
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i = j; //堆被破坏,需要重新调整
}
else{
break;
}
}
}
//输出构成的堆
System.out.print("原数据构成的堆:");
print(arr);
System.out.println();
//堆排序的算法(前提,已经构造成堆)
for(i = n-1; i>0; i--){
temp = arr[0]; //0号结点与第i个结点交换(i号结点也就是最后一个结点)
arr[0] = arr[i];
arr[i] = temp;
k = 0;
while(2*k+1<i){ //第i个结点有右子树
j=2*k+1;
if(j+1<i){
if(arr[j]<arr[j+1]){ //
j++;
}
}
if(arr[k]<arr[j]){
temp = arr[k];
arr[k] = arr[j];
arr[j] = temp;
k = j; //堆被破坏,需要重新调整
}
else{
break;
}
}
System.out.print("第"+(n-i)+"步排序结果:");
print(arr);
}
}
堆排序算法,平均速度为O(nlogn),最坏情况下的速度为O(nlogn)
(对比基本选择排序,O(n^2),O(n^2))
6、Shell排序
private static void shellSort(int[] arr){
int temp;
int j; //比较的一个下标
int x = 0;
for(int r = arr.length/2; r>=1; r=r/2){ //分组
for(int i = r; i < arr.length; i++){
temp = arr[i];
j = i -r; //注意这里减的是r,原因是分组进行比较
while(j>=0&&temp<arr[j]){
arr[j+r] = arr[j];
j = j-r;
}
arr[j+r] = temp;
}
x++;
System.out.print("第"+x+"趟的排序结果:");
print(arr);
}
}
Shell排序算法,平均速度O(n^(3/2)),最坏情况下的速度O(n^2)
(对比基本插入排序算法,O(n^2),O(n^2))
总结:当数据量较小时,可采用O(n^2)的算法,较大时,可采用O(nlogn)的算法