以下都是内部排序:
public class Sort {
public static void main(String[] args) {
int []a = {2,3,1,4,7,8,6,5,0};
int []b = {1,2,3,4};
//directChooseSort(a);
//bubbleSort(a);
//insertSort(a);
quickSort(a, 0, a.length-1);
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
//bubbleSort(b);
//for(int i=0;i<b.length;i++){
// System.out.print(b[i]+" ");
//}
}
/**
* 直接插入排序(属于插入排序),改进的方式是采用折半查找插入的位置
*/
public static void insertSort(int a[]){//最坏情况下,进行n-1趟,第i趟排序需要比较i次O(n^2) O(1) 稳定,从最大元素开始寻找插入位置,一般不会每个元素都比较
for(int i=0;i<a.length-1;i++){
if(a[i+1]<a[i]){//当无序表中的数据比有序表中的最大数据小时,才进行插入
int temp = a[i+1];
int j = i;
for(;j>=0&&temp<a[j];j--){
a[j+1]=a[j];
}
a[j+1]=temp;
}
}
}
/**
* 直接选择排序(属于选择排序) 堆排序 nlog2(n) O(1) 不稳定
* @param a
*/
public static void directChooseSort(int a[]){//进行n-1趟,第i趟排序需要比较n-i次 O(n^2) O(1) 不稳定
for(int i=0;i<a.length-1;i++){
int k = i;//本趟中最小的元素下标
for(int j=i+1;j<a.length;j++){
if(a[j]<a[k]){
k=j;
}
}
int temp = a[k];
a[k] = a[i];
a[i] = temp;
}
}
/**
* 冒泡排序(属于交换排序)
*/
public static void bubbleSort(int a[]){//进行n-1趟,第i趟排序需要比较n-i次O(n^2) O(1) 稳定,如果有序那么第一趟完成即可提前结束
for(int i=0;i<a.length-1;i++){
boolean flag = false;//通过flag判断是否可以提前结束排序
for(int j=0;j<a.length-i-1;j++){
if(a[j]>a[j+1]){
flag=true;
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
if(!flag){
System.out.println("排序提前结束");
break;
}
}
}
//直接插入排序和冒泡排序比直接选择排序要快,因为直接选择排序无论如何每一个元素都需要进行过比较
/**
* 快速排序(属于交换排序)
*/
public static void quickSort(int a[],int start,int end){ //O(nlog2(n)) O(log2(n)) 不稳定
if(start>=end){
return;
}
int i=start;
int j=end;
int temp=a[i];
while(i<j){
while(a[j]>=temp&&j>i) j--;
a[i]=a[j];
while(a[i]<=temp&&i<j) i++;
a[j]=a[i];
}
a[i]=temp;
quickSort(a, start, i-1);
quickSort(a, i+1, end);
}
}
堆排序:堆排序的要点就是调整堆和构造堆,其实构造堆也就是调整堆的过程
构造堆:将堆构造为一个大顶堆或者小顶堆,从最后一个非叶子节点(n/2,(n-1)/2)开始调整,比较该节点和该节点的左孩子与右孩子,选择出一个最大的,然后将该节点与其交换,交换之后如果被交换的孩子节点不满足大顶堆,那么对其进行调整
希尔排序:将整个待排元素分割成若干个子序列(相隔某个增量的元素组成)分别进行直接插入排序,待整个序列基本有序后,再对全体元素进行一次直接插入排序。