常见排序算法比较和实现

/**时间复杂度为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]);
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值