/**时间复杂度为O(nlogn)的方法有:快速排序、堆排序和归并排序;
时间复杂度为O(n2)的方法有:直接插入排序、冒泡排序和简单选择排序;
时间复杂度为O(n)的排序方法只有,基数排序,线性时间,基数排序与其他排序不同的是,不是基于数的比较。
如果是基于数之间的比较,则时间复杂度的下限为O(nlogn),不可能达到线性的。
排序方法的稳定性能:
稳定的排序方法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和经过排序之后,没有改变。
快速排序和堆排序是不稳定的排序方法。
*/
package Sortpkg;
public class FreqSort {
int[] array;
int len;
public FreqSort(int[] initArray) {
// TODO Auto-generated constructor stub
array=initArray;
len=initArray.length;
}
//插入排序 原址排序而且是稳定排序
void insertSort(int[] array){
int i,j;
for(j=1;j<array.length ;j++){
int temp=array[j];
for(i=j-1;i>=0 && array[i]>temp;i--){
array[i+1]=array[i];
}
array[i+1]=temp; //注意下标越界
}
System.out.println("插入排序:");
sortShow(array);
}
//折半插入排序,是基于简单插入排序基础上,对已排序的先进行折半查找,然后再移动插入最终位置
void binaryInsertSort(int[] array){
int i,j,low,high;
for(j=1;j<array.length;j++){
high=j-1;
int temp=array[j];
low=0;
while(low<=high){
int mid=(high+low)/2;
if(temp<array[mid])
high=mid-1;
else
low=mid+1;
}
for(i=j-1;i>=high;i--){
array[i+1]=array[i];
}
array[high+1]=temp;
}
System.out.println("折半插入排序:");
sortShow(array);
}
/**/希尔排序 是对插入排序的改进,如果数组基本有序,那么直接插入排序效是很高,基于根据这个特点。
//先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;
//然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止 ;
*/
/**冒泡排序
//两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。
*/
void bubbleSort(int[] array){
int i,j;
int temp;
boolean falg=false;
for(i=0;i<array.length ;i++){
for(j=0;j<array.length-i-1;j++){
if(array[j]>array[j+1]){
temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
falg=true;
}
}
if(falg==false){
break;
}
}
System.out.println("冒泡排序:");
sortShow(array);
}
/**快速排序
//快速排序简单说就是经过一趟排序之后,使得一个元素落在最终位置,且其前面所有元素比其小,后面元素比其大,然后进行递归……
//第一次选择基准很重要,不能使得问题每次划分成T(n)=T(n-1)+T(0)+O(n);这样就相当于插入排序,时间复杂度为O(n^2);
//为了不致情况很坏,可以应用随机快排;
*/
void quickSort(int[] array,int low,int high){
if(low<high){
int pMid=partition(array,low,high);
quickSort(array,low,pMid-1);
quickSort(array,pMid+1,high);
}
//sortShow(array);
}
int partition(int [] array,int low,int high){
int temp=array[low];
while(low<high){
while(low<high && array[high]>=temp)
--high;
array[low]=array[high];
while(low<high && array[low]<=temp)
++low;
array[high]=array[low];
}
array[low]=temp;
return low;
}
/**选择排序
//每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
*/
void selectSort(int[] array){
int i,j;
int temp;
for(i=0;i<array.length;i++){
int k=i;
for(j=i+1;j<array.length ;j++){
if(array[j]<array[k])
k=j;
}
if(k!=i){
temp=array[i];
array[i]=array[k];
array[k]=temp;
}
}
System.out.println("选择排序:");
sortShow(array);
}
/**计数排序
//是一种稳定的排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。
//计数排序不是比较排序,排序的速度快于任何比较排序算法。但需要的内存空间大;*/
void countSort(int[] a,int[] b,int len){
int[] c=new int[len+1];
for(int i=0;i<c.length;i++){
c[i]=0;
}//end
for(int j=0;j<a.length;j++){
c[a[j]]=c[a[j]]+1;
}//end for
for(int k=1;k<c.length;k++){
c[k]=c[k]+c[k-1];
}//end for
for(int j=a.length-1 ;j>=0;j--){
try{
b[c[a[j]]-1]=a[j];
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println(" "+a[j]+" "+c[a[j]]);
}
c[a[j]]=c[a[j]]-1;
}
}
//基数排序,要建立在一个稳定的排序基础之上
/**归并排序
//是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。
//将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。如此递归。*/
void mergeSort(int[] a,int low,int high){
if(low<high){
int mid=(low+high)/2;
mergeSort(a,mid+1,high);
mergeSort(a,low,mid);
merge(a,low,mid,high);
}
}
void merge(int[] a,int low,int mid ,int high){
int lLength=mid-low+1;
int rLength=high-mid;
int[] left=new int[lLength+1];
int[] right=new int[rLength+1];
for(int i=0;i<lLength;i++){
left[i]=a[low+i];
}
for(int j=0;j<rLength;j++){
right[j]=a[mid+j+1];
}
left[lLength]=Integer.MAX_VALUE;
right[rLength]=Integer.MAX_VALUE;
int i=0,j=0;
for(int k=low;k<=high;k++){
try{
if(left[i]<=right[j]){
a[k]=left[i];
i++;
}
else{
a[k]=right[j];
j++;
}
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(i+" "+a[i]+" "+j+" "+a[j]);
System.exit(-1);
}
}
}
void sortShow(int[] array){
for(int i=0;i<array.length ;i++){
System.out.print(" "+array[i]);
}
System.out.println();
}
}
//主函数
package Sortpkg;
public class SortDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] initArray={11,34,56,7,8,3,21,12,34,12,4,4,32};
FreqSort freqSort=new FreqSort(initArray);
freqSort.insertSort(initArray);
freqSort.binaryInsertSort(initArray);
freqSort.bubbleSort(initArray);
freqSort.quickSort(initArray, 0, initArray.length-1);
System.out.println("快速排序:");
for(int i=0;i<initArray.length ;i++){
System.out.print(" "+initArray[i]);
}
System.out.println();
freqSort.selectSort(initArray);
int max=0;
for(int i=0;i<initArray.length;i++){
if(initArray[i]>max){
max=initArray[i];
}
}
int[] b=new int[initArray.length];
freqSort.countSort(initArray, b, max);
System.out.println("计数排序:");
for(int i=0;i<b.length ;i++){
System.out.print(" "+b[i]);
}
System.out.println("\n归并排序:");
freqSort.mergeSort(initArray, 0, initArray.length-1);
for(int i=0;i<initArray.length ;i++){
System.out.print(" "+initArray[i]);
}
}
}