【algorithm】排序算法

交换排序

  • |–冒泡排序
    • |–快速排序
  • 插入排序
    • |–直接插入排序
    • |–希尔排序
  • 选择排序
    • |–简单选择排序
    • |–堆排序
  • 归并排序
  • 基数排序

【algorithm】排序算法_第1张图片

稳定排序:假设在待排序的文件中,存在了两个或两个以上的记录具有相同的关键字,在某种排序算法排序后,若这些相同关键字的元素的相对次序依然不变,则这种排序方法是稳定的。

  • 稳定:冒泡、插入、归并、基数
  • 不稳定:选择、快速、希尔、堆
public static void main(String[] args) {
    int[] arr = {3,9,7,6,8,4,5,10,2,1};
    for (int i : arr) {
        System.out.print(i+" ");
    }
    System.out.println();
    //bubbleSort(arr);
    //quickSort(arr, 0, arr.length-1);
    //insertSort(arr);
    //shellSort(arr);
    //selectSort(arr);
    heapSort(arr, arr.length);
    //int[] merge = new int[10];
    //mergeSort(arr, merge, 0, arr.length-1);
    //basketSort(arr);
    for (int i : arr) {
        System.out.print(i+" ");
    }
    System.out.println();
}

public static void swap(int[] arr,int i,int j){
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

冒泡

/*
冒泡排序
最好时间复杂度 o(n),最坏时间复杂度o(n^2),平均o(n^2),稳定
*/
public static void bubbleSort(int[] arr){
    if (arr == null || arr.length == 0) {
        return;
    }
    for (int i = 0; i < arr.length-1; i++) {
        for (int j = 0; j < arr.length-1-i; j++) {
            if (arr[j] > arr[j+1]) {
                swap(arr,j,j+1);
            }
        }
    }
}

每趟排序结果:

 start : 3 9 7 6 8 4 5 10 2 1 
process: 3 7 6 8 4 5 9 2 1 10 
process: 3 6 7 4 5 8 2 1 9 10 
process: 3 6 4 5 7 2 1 8 9 10 
process: 3 4 5 6 2 1 7 8 9 10 
process: 3 4 5 2 1 6 7 8 9 10 
process: 3 4 2 1 5 6 7 8 9 10 
process: 3 2 1 4 5 6 7 8 9 10 
process: 2 1 3 4 5 6 7 8 9 10 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

快排

/*
 * 快速排序
 * 最好时间复杂度 o(nlog(2)n),最坏时间复杂度o(n^2),平均o(n^2),不稳定
 */
public static void quickSort(int[] arr,int left,int right){
  //左边索引小于右边,则还未排序完成  
  if (left < right) {
    //取中间的元素作为比较基准,小于他的往左边移,大于他的往右边移 
    int mid = arr[(left+right)/2];
    int i = left - 1;
    int j = right + 1;
    while (true) {
      //移动下标,左边的往右移动,右边的向左移动
      while(arr[++i] < mid && i < right);
      while(arr[--j] > mid && j > left);
      if (i >= j) break;
      swap(arr, i, j);
    }
    quickSort(arr, left, i-1);
    quickSort(arr, j+1, right);
  }
}

每趟排序结果:

 start : 3 9 7 6 8 4 5 10 2 1 
process: 3 1 7 6 2 4 5 10 8 9 
process: 3 1 5 4 2 6 7 10 8 9 
process: 3 1 2 4 5 6 7 10 8 9 
process: 1 3 2 4 5 6 7 10 8 9 
process: 1 2 3 4 5 6 7 10 8 9 
process: 1 2 3 4 5 6 7 10 8 9 
process: 1 2 3 4 5 6 7 10 8 9 
process: 1 2 3 4 5 6 7 8 10 9 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

插入排序

/*
 * 直接插入排序
 * 最好时间复杂度o(1),最坏时间复杂度o(n^2),平均o(n^2),稳定
 */
public static void insertSort(int[] arr){
  //直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的
  for (int i = 1; i < arr.length; i++) {
    if (arr[i] < arr[i-1]) {
      //用一个变量来保存当前待比较的数值,因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位 
      int temp = arr[i];
      int j = 0;
      for(j = i-1;j >= 0 && temp < arr[j];j--)
        arr[j+1] = arr[j];
      arr[j+1] = temp;
    }
  }
}

每趟排序结果:

 start : 3 9 7 6 8 4 5 10 2 1 
process: 3 9 7 6 8 4 5 10 2 1 
process: 3 7 9 6 8 4 5 10 2 1 
process: 3 6 7 9 8 4 5 10 2 1 
process: 3 6 7 8 9 4 5 10 2 1 
process: 3 4 6 7 8 9 5 10 2 1 
process: 3 4 5 6 7 8 9 10 2 1 
process: 3 4 5 6 7 8 9 10 2 1 
process: 2 3 4 5 6 7 8 9 10 1 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

希尔排序

 /* *
  * 希尔排序
  * 最好时间复杂度o(n),最坏时间复杂度o(n^2),平均o(n^1.3),不稳定
  */
    public static void shellSort(int[] arr){
        int len = arr.length;
        for (int h = len/2; h > 0; h = h / 2) {
            for(int i = h; i < len; i++){
                for (int j = i-h; j > 0 && arr[j] > arr[j + h]; j -= h) {
                    swap(arr, j, j + h);
                }
            }
        }
    }

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 
process: 3 5 7 2 1 4 9 10 6 8 
process: 3 2 1 4 6 5 7 8 9 10 
process: 3 1 2 4 5 6 7 8 9 10 
  end  : 3 1 2 4 5 6 7 8 9 10 

选择排序

/*
 * 简单选择排序
 * 最好时间复杂度o(n^2),最坏时间复杂度o(n^2),平均o(n^2),不稳定
 */
public static void selectSort(int[] arr){
  int min = 0;
  for (int i = 0; i < arr.length; i++) {
    min = i;
    for (int j = i + 1; j < arr.length; j++) {
      if (arr[min] > arr[j]) {
        min = j;
      }
    }
    if (min != i) {
      swap(arr, min, i);
    }
  }
}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 
process: 1 9 7 6 8 4 5 10 2 3 
process: 1 2 7 6 8 4 5 10 9 3 
process: 1 2 3 6 8 4 5 10 9 7 
process: 1 2 3 4 8 6 5 10 9 7 
process: 1 2 3 4 5 6 8 10 9 7 
process: 1 2 3 4 5 6 8 10 9 7 
process: 1 2 3 4 5 6 7 10 9 8 
process: 1 2 3 4 5 6 7 8 9 10 
process: 1 2 3 4 5 6 7 8 9 10 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

堆排序

/*
 * 堆排序 
 */
public static void heapSort(int[] arr,int top){
  //建一个初始的大根堆
  for (int i = arr.length / 2 - 1; i >= 0; i--) {
    heapAdjust(arr,i,arr.length);
  }
  for (int i = 0; i < arr.length; i++) {    
    System.out.print(arr[i] + "  ");
  }
  System.out.println();
  for (int i = arr.length - 1; i >= arr.length - top; i--){
    swap(arr, 0, i);
    heapAdjust(arr, 0, i);
  }
}
private static void heapAdjust(int[] arr,int parent,int len){
  int temp = arr[parent];
  //左结点
  int child = 2*parent + 1;
  while (child < len) {
    //找出两个子结点中较大的一个
    if (child + 1 < len && arr[child] < arr[child + 1]) 
      child++;
    //如果父节点大于子结点中较大的一个,退出。
    if(temp >= arr[child]) break;
    //将比子结点大的值赋值给父结点
    arr[parent] = arr[child];
    parent = child;
    child = 2 * parent + 1;
  }
  arr[parent] = temp;
}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 
initheap:10 9 7 6 8 4 5 3 2 1  
process: 9 8 7 6 1 4 5 3 2 10 
process: 8 6 7 3 1 4 5 2 9 10 
process: 7 6 5 3 1 4 2 8 9 10 
process: 6 3 5 2 1 4 7 8 9 10 
process: 5 3 4 2 1 6 7 8 9 10 
process: 4 3 1 2 5 6 7 8 9 10 
process: 3 2 1 4 5 6 7 8 9 10 
process: 2 1 3 4 5 6 7 8 9 10 
process: 1 2 3 4 5 6 7 8 9 10 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

归并排序

/*
 * 归并排序
 * 算法规则:
 * 1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
 * 2.设定两个指针,最初位置分别为两个已经排序序列的起始位置 
 * 3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 
 * 4.重复步骤3直到某一指针到达序列尾 
 * 5.将另一序列剩下的所有元素直接复制到合并序列尾
 */
public static void mergeSort(int[] arr,int[] merge,int first,int last){
  if (first >= last) return;
  int mid = (last + first) >> 1;
  mergeSort(arr, merge, first, mid);
  mergeSort(arr, merge, mid + 1, last);
  merger(arr, merge, first,last,mid);
}
private static void merger(int[] arr, int[] merge, int first, int last,int mid) 
{
  System.out.print("first:"+first+",last:"+last+",mid:"+mid+" : ");
  int i = first;
  int j = mid+1;
  int pos = first;
  while( i <= mid || j <= last ){
    if( i > mid ){
      while( j <= last ) merge[pos++] = arr[j++];
      break;
    }

    if( j > last ){
      while( i <= mid ) merge[pos++] = arr[i++];
      break;
    }
    //等于小的
    merge[pos++] = arr[i] >= arr[j] ? arr[j++] : arr[i++];
  }

  for (pos = first; pos <= last; pos++){
    arr[pos] = merge[pos];
    System.out.print(arr[pos]+" ");
  }
  System.out.println();
}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 
first:0,last:1,mid:0 : 3 9 
process: 3 9 7 6 8 4 5 10 2 1 
first:0,last:2,mid:1 : 3 7 9 
process: 3 7 9 6 8 4 5 10 2 1 
first:3,last:4,mid:3 : 6 8 
process: 3 7 9 6 8 4 5 10 2 1 
first:0,last:4,mid:2 : 3 6 7 8 9 
process: 3 6 7 8 9 4 5 10 2 1 
first:5,last:6,mid:5 : 4 5 
process: 3 6 7 8 9 4 5 10 2 1 
first:5,last:7,mid:6 : 4 5 10 
process: 3 6 7 8 9 4 5 10 2 1 
first:8,last:9,mid:8 : 1 2 
process: 3 6 7 8 9 4 5 10 1 2 
first:5,last:9,mid:7 : 1 2 4 5 10 
process: 3 6 7 8 9 1 2 4 5 10 
first:0,last:9,mid:4 : 1 2 3 4 5 6 7 8 9 10 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

基数排序

/*
 * 基数排序(桶排序)
 */
public static void basketSort(int arr[])//arr为待排序数组
{
  int len=arr.length;
  int bask[][]=new int[10][len];
  int index[]=new int[10];
  int max=Integer.MIN_VALUE;
  System.out.println(max);
  //找到数组中长度最大的数的长度 max
  for(int i=0;i(Integer.toString(arr[i]).length())?max:(Integer.toString(arr[i]).length());
  }
  String str;
  //先将长度相同的元素放在一起,并且按照长度进行排序
  //然后将长度相同的元素排序。
  for(int i=max-1;i>=0;i--){
    for(int j=0;j"";
      //如果数组有的元素的长度小于最大长度,补0
      if(Integer.toString(arr[j]).length()for(int k=0;k"0";
      }
      str+=Integer.toString(arr[j]);
      bask[str.charAt(i)-'0'][index[str.charAt(i)-'0']++]=arr[j];
    }
    int pos=0;
    for(int j=0;j<10;j++)
    {
      for(int k=0;kfor(int x=0;x<10;x++)
      index[x]=0;
  }
}

每趟排序之后:

 start : 3 9 7 6 8 4 5 10 2 1 
process: 10 1 2 3 4 5 6 7 8 9 
process: 1 2 3 4 5 6 7 8 9 10 
  end  : 1 2 3 4 5 6 7 8 9 10 

你可能感兴趣的:(algorithm)