排序算法

来源:互联网 发布:tekla软件 价格 编辑:程序博客网 时间:2024/06/18 15:56
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){  //...   }}


 

原创粉丝点击