排序算法

package edu.mit.sort;

import java.util.Random;

public class SortUtils {

 public static void main(String[] args) {
  
  //int[] arr = {6,10,13,5,8,3,2,11};
  int[] arr = {5,5,2,1,3,7,6,6,9,11,14,12,12,12,10,13,10};
  System.out.print("排序前:");
  for(int i=0;i<arr.length;i++){
   System.out.print(arr[i]+"  ");
  }
  System.out.println();
  
  //bubbleSort(arr);
  //insertSort(arr);
  //mergeSort(arr,0,arr.length-1,new int[arr.length]);
  //randomQuickSort(arr,0,arr.length-1);
  countSort(arr);
  
  System.out.print("排序后:");
  for(int i=0;i<arr.length;i++){
   System.out.print(arr[i]+"  ");
  }
  
  /*int[] a1 = {1,3,5,7,9};
  int[] a2 = {2,4,6,8,10};
  int[] arr = mergeSort(a1,a2);
  for(int i=0;i<arr.length;i++){
   System.out.print(arr[i]+"  ");
  }*/
 }
 
 /**
  * for i = 0 to n
  *  for j = i+1 to n
  *   do if arr[j]<arr[i]
  *    then exch arr[j]<->arr[i]
  * 
  * 每次外循环,arr[i->n]中最小的元素都会被交换到前面<br/>
  * 时间复杂度O(n^2) 
  * @param arr
  */
 public static void bubbleSort(int[] arr){
  
  int n = arr.length;
  
  for(int i=0;i<n;i++){
   
   for(int j=i+1;j<n;j++){
    
    if(arr[i]>arr[j]){
     arr[i] = arr[i]^arr[j];
     arr[j] = arr[i]^arr[j];
     arr[i] = arr[i]^arr[j];
    }
   }
  }
  
 }
 
 /**
  * for j = 1 to n
  *  i <-- j,tmp = a[j]
  *  while i>0 && a[j] < a[i-1]
  *   a[i] <-- a[i-1]; i--;
  *  a[i] = tmp;
  *  
  *  ⒈ 从第一个元素开始,该元素可以认为已经被排序
  *  ⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描
  *  ⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置
  *  ⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  *  ⒌ 将新元素插入到下一位置中
  *  ⒍ 重复步骤2
  * 时间复杂度O(n^2)
  * @param arr
  */
 public static void insertSort(int[] arr){
  
  int n = arr.length;
  
  for(int j=1;j<n;j++){
   int i = j;
   int tmp = arr[j];//insert element
   while(i>0&&tmp<arr[i-1]){
    arr[i] = arr[i-1];//move to next position
    i--;
   }
   arr[i] = tmp;
  }
 }
 
 /**
  * 归并排序 时间复杂度O(nlgn)
  * @param arr 要排序的数组
  * @param begin 起始点(包含)
  * @param end 结束点(包含)
  * @param tmp 存放中间结果,最后作为返回值
  */
 public static void mergeSort(int[] arr,int begin,int end,int[] tmp){
  if(begin<end){
   int mid = (begin+end)/2;
   mergeSort(arr,begin,mid,tmp);//相当于左子树
   mergeSort(arr,mid+1,end,tmp);
   
   int i=begin,j=mid+1;
   int k=begin;
   while(i<=mid && j<=end){//每次选最小的
    if(arr[i]<arr[j]){
     tmp[k++] = arr[i++];
    }else{
     tmp[k++] = arr[j++];
    }
   } 
   while(i<=mid){//剩下的
    tmp[k++] = arr[i++];
   }
   while(j<=end){//剩下的
    tmp[k++] = arr[j++];
   }
   for(i=begin;i<=end;i++){//写回原数组
    arr[i] = tmp[i];
   }
  }
  
 }
 
 /**
  * 时间复杂度O(n+m)
  * @param a1
  * @param a2
  * @return
  */
 public static int[] mergeSort(int[] a1,int[] a2){
  int len1 = a1.length;
  int len2 = a2.length;
  int len = len1 + len2;
  int[] a = new int[len];
  int i=0,j=0,k=0;
  while(i<len1 && j<len2){//每次选最小的
   if(a1[i]<a2[j]){
    a[k] = a1[i];
    i++;
   }else{
    a[k] = a2[j];
    j++;
   }
   k++;
  } 
  while(i<len1){//剩下的
   a[k++] = a1[i++];
  }
  while(j<len2){//剩下的
   a[k++] = a2[j++];
  }
  return a;
  
 }
 
 public static void quickSort(int[] arr,int begin,int end){
  
  int key = arr[begin];//pivot
  int i = begin;
  for(int j=begin+1;j<=end;j++){
   if(arr[j]<key){// 小于关键字的都丢到左边
    i++;
    if(i!=j){
     arr[i] = arr[i]^arr[j];
     arr[j] = arr[i]^arr[j];
     arr[i] = arr[i]^arr[j];
    }
   }
  }
  //比关键字放到i处,使得大于key的都在左边,小于key的都在右边
  
  if(i!=begin){
   arr[i] = arr[i]^arr[begin];
   arr[begin] = arr[i]^arr[begin];
   arr[i] = arr[i]^arr[begin];
  }
  if(i-begin>1){
   quickSort(arr,begin,i-1);
  }
  if(end-i>1){
   quickSort(arr,i+1,end);
  }
  
 }
 
 public static void randomQuickSort(int[] arr,int begin,int end){
  Random r= new Random();
  int pos = begin + r.nextInt(end-begin);
  int key = arr[pos];//pivot
  int i = begin;
  for(int j=begin+1;j<=end;j++){
   if(arr[j]<key){// 小于关键字的都丢到左边
    i++;
    if(i!=j){
     arr[i] = arr[i]^arr[j];
     arr[j] = arr[i]^arr[j];
     arr[i] = arr[i]^arr[j];
    }
   }
  }
  //比关键字放到i处,使得大于key的都在左边,小于key的都在右边
  
  if(i!=begin){
   arr[i] = arr[i]^arr[begin];
   arr[begin] = arr[i]^arr[begin];
   arr[i] = arr[i]^arr[begin];
  }
  if(i-begin>1){
   quickSort(arr,begin,i-1);
  }
  if(end-i>1){
   quickSort(arr,i+1,end);
  }
  
  
 }
 
 /**
  * 适用于数组中最大元素比较小,数据比较集中的情况
  * @param arr
  */
 public static void countSort(int[] arr){
  int[] tmp = new int[arr.length];
  int[] counts = new int[1024];//假设arr中的元素都小于1024
  for(int i=0;i<arr.length;i++){
   counts[arr[i]]++;
  }
  for(int i=1;i<1024;i++){
   counts[i] = counts[i] + counts[i-1];
  }
  for(int i=0;i<arr.length;i++){
   if(counts[arr[i]]>0){
    tmp[counts[arr[i]]-1] = arr[i];
    counts[arr[i]]--;
   }
  }
  for(int i=0;i<arr.length;i++){//写回原数组
   arr[i]=tmp[i];
  }
 }
 
 /**
  * 适用于数组元素长度相同的情况
  * 先对个位排序,再十位,然后百位..借助于计数排序的原理,轮询次数为数的长度,如果借助较大
  * 辅助空间(多位一组)可以让其更快,时间复杂度为O(n)
  * 
  * @param arr
  */
 public static void baseCount(int[] arr){
  //...
  
 }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值